14.B树

来源:互联网 发布:淘宝联盟 分享店铺 编辑:程序博客网 时间:2024/06/01 15:26

B树

#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define T 4typedef struct B_Tree_Node{int n;//指示该结点的关键字个数  int *keys;//该结点关键字数组int isLeaf;//该结点是否是叶子结点struct B_Tree_Node **child;//该结点的所有孩子结点struct B_Tree_Node *p; //该结点的父结点}B_Tree_Node,*p_B_Tree_Node;//生成一个新的B树结点B_Tree_Node *alloact_Node(){int i;B_Tree_Node *newNode=(B_Tree_Node *)malloc(sizeof(B_Tree_Node));newNode->n=0;newNode->isLeaf=TRUE;newNode->keys=(int *) malloc((2*T-1) * sizeof(int));newNode->child=(p_B_Tree_Node *) malloc((2*T) * sizeof(p_B_Tree_Node));newNode->p=NULL;for(i=0;i<2*T;i++)newNode->child[i]=NULL;return newNode;}//splitNode_p是被分裂结点的父结点,i是索引为i的孩子为满,需要被分裂  //被分裂的结点是满的,那么它的n = 2*T - 1;被分裂为两个T-1个关键字的子结点,同时它的中间元素被提升到其父节点中  void BTree_Child_Split(B_Tree_Node *splitNode_p, int index_child)  {  int i;    B_Tree_Node *newChild = alloact_Node();      newChild->n = T-1;      for(i = 0;i<T-1;i++)      {          newChild->keys[i] = splitNode_p->child[index_child]->keys[T+i];      }      splitNode_p->child[index_child]->n = T-1;      if(splitNode_p->child[index_child]->isLeaf!=TRUE)  //如果它的第i个孩子不是叶子结点,则将它的后T个孩子也送给newChild      {          newChild->isLeaf = FALSE;          for(i=0;i<T-1;i++)              newChild->child[i] = splitNode_p->child[i+T];      }      //将newChild 添加为splitNode_p的第i+1个孩子结点,将中间关键字提升到它中      for(i = splitNode_p->n; i>=index_child;i--)      {          splitNode_p->child[i+1] = splitNode_p->child[i];      }      splitNode_p->n++;      splitNode_p->child[index_child+1] = newChild;      for(splitNode_p->n-1; i>=index_child;i--)      {          splitNode_p->keys[i+1] = splitNode_p->keys[i];      }      splitNode_p->keys[index_child] = splitNode_p->child[index_child]->keys[T-1];  }  //在未满的结点插入元素void BTree_Insert_NonFull(B_Tree_Node *nonfull, int k)  {      int i = nonfull->n - 1;      if(nonfull->isLeaf)      {          while(i>=0&&k<nonfull->keys[i])          {              nonfull->keys[i+1] = nonfull->keys[i];              i--;          }          i = i+1;          (nonfull->n)++;          nonfull->keys[i] = k;      }      else      {          while(i>=0&&k<nonfull->keys[i])              i--;          i = i+1;          if(nonfull->child[i]->n == 2*T-1)          {              BTree_Child_Split(nonfull,i);              if(k>nonfull->keys[i])                  i = i+1;          }          BTree_Insert_NonFull(nonfull->child[i],k);      }  }  //在B_Tree中加入新的关键字,主要由BTree_Insert_NonFull来实现,确保每次插入时所访问的结点都是非满结点;  //首先,若根结点为满,则分裂根结点  void BTree_Insert_Node(p_B_Tree_Node *root,int k)  {      B_Tree_Node *p = *root;      if(p->n == 2*T - 1) //如果根结点满      {          B_Tree_Node *newRoot =alloact_Node();          newRoot->child[0] = (*root);          newRoot->isLeaf = FALSE;          *root = newRoot;                    BTree_Child_Split(newRoot,0);          BTree_Insert_NonFull(newRoot,k);      }      else           BTree_Insert_NonFull(*root,k);  }  //广度优先搜索遍历输出void printBFS(B_Tree_Node *t)  {  int i;    if(NULL == t)          return;        //输出当前节点所有关键字      printf("    [");      for(i = 0;i < t->n;++i)      {          printf("%d", t->keys[i]);          if(t->n - 1 != i)             printf(" ");      }      printf("]\n");        //递归输出所有子树      for(i = 0;i <= t->n;++i)          printBFS(t->child[i]);}  //构造B树void createBTree(p_B_Tree_Node *root)  {  int i;    int a[] = {12,1,9,2,0,11,7,19,4,15,18,5,14,13,10,16,6,3,8,17};      for(i = 0;i<20;i++)      {          BTree_Insert_Node(root,a[i]);  printf("插入元素%d后\n",a[i]);        printBFS(*root);      }  }  int main(){B_Tree_Node *root; //B树根结点 root = alloact_Node(); //构造B树createBTree(&root); return 0;}


0 0
原创粉丝点击