插入B树

时间:2016-05-13 01:03:16

标签: c data-structures tree b-tree

大家。我在C语言中实现了BTree的插入函数时遇到了一些麻烦。我正在尝试从Cormen的书中练习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”在两个不同的级别中调用,也许可以与之相关?)。当我打印树时,T的孩子没有显示。我真的不知道该做什么......我被困住了,无法弄清楚我做错了什么。有人知道我该如何修复实施?这些是插入'W'和'M'后的结果。

更多信息已添加BELLOW:

W之后(此时还可以)[printBtree显示的内容]:

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

在真正的b树中表示:

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

M [什么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”从树中消失。 / p>

0 个答案:

没有答案