Вставка в B-дерево

Каждый. У меня возникли небольшие проблемы с реализацией функции вставки BTree в C. Я пытаюсь выполнить упражнение 18-2.1 из книги Кормена и построчно следую алгоритму, содержащемуся в книге, но даже в этом случае я не могу заставить его работать должным образом. Вот мой код:

#define TYPE char

#define T 2
#define NOT_FOUND -1
#define TRUE 1
#define FALSE 0


typedef struct _node {
  int n;
  int leaf;
  TYPE keys[2 * T - 1];
  struct _node *child[2 * T];
} Node, BTree;

/-----------------------------/

BTree* createBtree () {
   BTree *a = (BTree *)malloc(sizeof(BTree));
   a->n = 0;
   a->leaf = TRUE;
   return a;
}


void printBtree (BTree *a, int level) {
   int i;


   for (i = 0; i < level; i++) { printf("  "); }


   printf("|");
   for (i = 0; i < a->n; i++) {
      printf("%c|", a->keys[i]);

   }
   printf("\n");


   for (i = 0; i <= a->n; i++) {
      if (a->leaf == FALSE) {
         printBtree(a->child[i], level + 1);
      }
   }
}


BTree* splitNode (BTree *x, int i, BTree *y) {
    int j;
    BTree *z = createBtree();
    z->n = T - 1;

    for (j = 0; j < T - 1; j++){
        z->keys[j] = y->keys[j+T];
    }

    if (y->leaf == FALSE)
    {
        for (j = 0; j < T; j++){
            z->child[j] = y->child[j+T];
        }
    }

    y->n = T - 1;

    for (j = x->n; j >= i+1; j--){
        x->child[j+1] = x->child[j];
    }

    x->child[i+1] = z;


    for (j = x->n-1; j >= i; j--){
        x->keys[j+1] = x->keys[j];
    }

    x->keys[i] = y->keys[T-1];


    x->n++;


   return x;
}

BTree* insertNonFull (BTree *x, TYPE k) {
    int i = x->n-1;

    if (x->leaf == TRUE){

        while (i >= 0 && x->keys[i] > k){
            x->keys[i+1] = x->keys[i];
            i--;
        }


        x->keys[i+1] = k;
        x->n++;


    }
    else
    {
        while (i >= 0 && x->keys[i] > k){
            i--;
        }

        i = i + 1;

        if (x->child[i]->n == 2*T-1){
            x = splitNode(x, i, x->child[i]);

            if (k > x->keys[i]){
                i = i + 1;
            }
        }

        x->child[i] = insertNonFull(x->child[i], k);
    }

    return x;
}


BTree *insert (BTree *root, TYPE keys) {
   BTree *r = root;
   if (r->n == (2*T - 1)) {
      BTree *s = createBtree();
      s->leaf = FALSE;
      s->child[0] = r;
      s = splitNode (s, 0, r);
      s = insertNonFull (s, keys);
      return s;
   }
   else {
      return insertNonFull (r, keys);
   }
}




int main () {

   BTree *a = createBtree();

   a = insert (a, 'F');
   a = insert (a, 'S');
   a = insert (a, 'Q');
   a = insert (a, 'K');
   a = insert (a, 'C');
   a = insert (a, 'L');
   a = insert (a, 'H');
   a = insert (a, 'T');
   a = insert (a, 'V');
   a = insert (a, 'W');
   a = insert (a, 'M');
   a = insert (a, 'R');
   a = insert (a, 'N');
   a = insert (a, 'P');
   a = insert (a, 'A');
   a = insert (a, 'B');
   a = insert (a, 'X');
   a = insert (a, 'Y');
   a = insert (a, 'D');
   a = insert (a, 'Z');
   a = insert (a, 'E');

   printBtree(a, 0);


   return 0;
}

Это работает очень хорошо, пока я не вставлю 'M' в дерево ("splitChild" вызывается на двух разных уровнях, может быть, это может быть что-то связанное с этим?). "Дети Т не показывают, когда я печатаю дерево. Я действительно не знаю, что делать в этот момент... Я застрял и не могу понять, что я делаю неправильно. Кто-нибудь знает, как можно исправить реализацию? Это результаты после вставки "W" и "M".

БОЛЬШЕ ИНФОРМАЦИИ, ДОБАВЛЕННОЙ НИЖЕ

После W (все нормально на этом этапе) [Что показывает printBtree]:

|F|Q|T|
  |C|
  |H|K|L|
  |S|
  |V|W|

Представление в реальном b-дереве:

        | F | Q | T |
      /     |    \   \ 
     /      |     \   \ 
    |C| |H|K|L|   |S|  |V|W|

После М [Что показывает printBtree]

|Q|
   |F|K|
     |C|
     |H|
     |L|M|
   |T|

Представление в реальном b-дереве:

                 | Q |
                /     \ 
               /       \ 
          |F|K|         |T|
         /  | \ 
        /   |  \
      |C|  |H| |L|M|

Что должно было показать:

 |Q|
   |F|K|
     |C|
     |H|
     |L|M|
   |T|
     |S|
     |V|W|

После вызова функции разделения на двух разных уровнях дерева (узлы "H,K,L" и узлы "F,Q,T"), "S" и "V,W" исчезают из дерева.

0 ответов

Другие вопросы по тегам