码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构【查找】—B树

时间:2019-03-25 11:00:53      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:向量   class   个数   style   讲解   insert   库函数   lse   ptr   

/*********************讲解后期补充*****************/

先上代码

  1 #include "000库函数.h"
  2 
  3 
  4 #define MAXSIZE 100//存储空间
  5 
  6 #define m 3//B树的阶
  7 #define N 17//数据元素的个数
  8 #define MAX 5//字符串的最大长度
  9 
 10 struct BTree
 11 {
 12     int keynum;//节点中关键字的个数 即节点大小
 13     BTree *parent;//指向双亲的指针
 14     struct Node//节点向量类型
 15     {
 16         int key;//关键字向量
 17         BTree *ptr;//子树指针向量
 18         int recptr;//记录指针向量
 19     };
 20     Node node[m + 1];//0号单元未使用
 21 };
 22 
 23 
 24 struct Result{
 25     BTree *pt;//指向找到的节点
 26     int i;//在节点中的关键字序号
 27     int tag;//查找成功与否
 28 };
 29 
 30 int Search(BTree *p, int elem) {//p.node[i].key<=elem<p.node[i+1].key
 31     int j;
 32     for (int i = 1; i < p->keynum; ++i)
 33         if (p->node[i].key <= elem)
 34             j = i;
 35     return j;
 36 }
 37 
 38 //查找B树中是否存在该数
 39 /*关键字应该插在指针pt所指节点中的第i和第i+1个关键字之间*/
 40 Result* SearchBTree(BTree *T, int elem) {
 41     BTree *p, *q;
 42     p = T;
 43     q = NULL;
 44     int find = false;
 45     Result *r = new Result;
 46     int i = 0;
 47     while (p && !find) {
 48         i = Search(p, elem);//p.node[i].key<=elem<p.node[i+1].key
 49         if (i > 0 && p->node[i].key == elem)//查找到了关键字
 50             find = true;
 51         else {
 52             q = p;
 53             p = p->node[i].ptr;
 54         }
 55     }
 56     r->i = i;
 57     if(find){//查找成功
 58         r->pt = p;
 59         r->tag = 1;
 60     }
 61     else {//查找不成功,返回elem的插入位置的信息
 62         r->pt = q;
 63         r->tag = 0;
 64     }
 65     return r;
 66 }
 67 
 68 /* 将r->key、r和ap分别插入到q->key[i+1]、q->recptr[i+1]和q->ptr[i+1]中 */
 69 int Insert(BTree* &pt, int n, int rx, BTree *ap) {
 70     for (int i = pt->keynum; i > n; --i)//空出pt->node[n+1]
 71         pt->node[i + 1] = pt->node[i];//向后挪,腾出位置来
 72     pt->node[n + 1].key = rx;
 73     pt->node[n + 1].ptr = ap;
 74     pt->node[n + 1].recptr = rx;
 75     pt->keynum++;
 76     return true;
 77 }
 78 
 79 /* 将结点q分裂成两个结点,前一半保留,后一半移入新生结点ap */
 80 int split(BTree* &pt, BTree* &ap) {
 81     int s = (m + 1) / 2;
 82     ap = new BTree;//生成新的节点ap
 83     ap->node[0].ptr = pt->node[s].ptr;//后一半移入ap中
 84     for (int i = s + 1; i < m; ++i) {
 85         ap->node[i - s] = pt->node[i];
 86         if (ap->node[i - s].ptr)
 87             ap->node[i - s].ptr->parent = ap;
 88     }
 89     ap->keynum = m - s;
 90     ap->parent = pt->parent;
 91     pt->keynum = s - 1;/*  q的前一半保留,修改keynum */ 
 92 
 93     return true;
 94 }
 95 
 96 /* 生成含信息(T,r,ap)的新的根结点&T,原T和ap为子树指针 */
 97 int NewRoot(BTree *T, int key, BTree *ap) {
 98     BTree *p = new BTree;
 99     p->node[0].ptr = T;
100     T = p;
101     if (T->node[0].ptr)
102         T->node[0].ptr->parent = T;
103     T->parent = NULL;
104     T->keynum = 1;
105     T->node[1].key = key;
106     T->node[1].recptr = key;
107     T->node[1].ptr = ap;
108     if (T->node[1].ptr)
109         T->node[1].ptr->parent = T;
110 
111     return true;
112 }
113 
114 /*  在m阶B树T上结点*q的key[i]与key[i+1]之间插入关键字K的指针r。若引起 */
115 /*  结点过大,则沿双亲链进行必要的结点分裂调整,使T仍是m阶B树。 */
116 int InsertBTree(BTree* &T, int elem, BTree *pt, int n) {
117     BTree *ap;
118     ap = new BTree;
119     bool finished = false;
120     int s, rx;
121     rx = elem;
122     while (pt && !finished) {
123         Insert(pt, n, rx, ap);// 将r->key、r和ap分别插入到q->key[i+1]、q->recptr[n+1]和q->ptr[n+1]中  */
124         if (pt->keynum < m)
125             finished = true;//插入成功
126         else {//对节点进行分裂
127             s = (m + 1) / 2;
128             rx = pt->node[s].recptr;
129             split(pt, ap);/*  将q->key[s+1..m],q->ptr[s..m]和q->recptr[s+1..m]移入新结点*ap  */
130             pt = pt->parent;
131             if (pt)
132                 n = Search(pt, elem);//在双亲结点中*q中查找rx->key的插入位置
133         }
134     }
135     if (!finished)/*  T是空树(参数q初值为NULL)或根结点已分裂为结点*q和*ap */
136         NewRoot(T, rx, ap);/*  生成含信息(T,rx,ap)的新的根结点*T,原T和ap为子树指针 */
137 
138     return true;
139 }
140         
141 
142 int T034()
143 {
144     int r[N] = { 22,16,41,58,8,11,12,16,17,22,23,31,41,52,58,59,61 };
145     BTree *T = new BTree;
146     T = NULL;
147     Result *s;
148     for (int i = 0; i < N; i++)
149     {
150         s = SearchBTree(T, r[i]);
151         if (!s->tag)
152             InsertBTree(T, r[i], s->pt, s->i);
153     }
154     printf("\n请输入待查找记录的关键字: ");
155     int a;
156     scanf("%d", &a);
157     s = SearchBTree(T, a);
158     if (s->tag)
159         printf("(%d)", (s->pt)->node[a].key);
160     else
161         printf("没找到");
162     printf("\n");
163 
164     return 0;
165 }

 

数据结构【查找】—B树

标签:向量   class   个数   style   讲解   insert   库函数   lse   ptr   

原文地址:https://www.cnblogs.com/zzw1024/p/10592195.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!