欢迎来到冰豆网! | 帮助中心 分享价值,成长自我!
冰豆网
全部分类
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • 党团工作>
  • ImageVerifierCode 换一换
    首页 冰豆网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    B+树的代码实现.docx

    • 资源ID:29771672       资源大小:19.42KB        全文页数:22页
    • 资源格式: DOCX        下载积分:10金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    B+树的代码实现.docx

    1、B+树的代码实现B+树的实现。这个B+树是建立在操作系统的文件系统之上的,并没有自己的文件系统。B+树的节点全部存储在一个文件中。由于每个节点的大小是相同的,所以我对每个节点 进行编号,即每个节点的id。这样每个节点在文件的字节位置就可以通过计算sizeof(BPNode)*(c-id - 1)得到。 所以,每个B+树的节点有一个id属性,就是记录自己的标号。 同时对B+树建立一个结构体,这个结构体中的root属性,用于指向读入内存后的树的根节点。 locate属性记录树的根节点的在文件中的标号。num属性记录这棵树的节点个数,每次新增一个节点都会加一。 name属性记录用于存储这个B+树的文

    2、件名(相对cpp文件所在的文件夹),fp属性用于记录打开这个文件时的文件指针 因为这个文件只记录B+树的节点,所以每次插入的时候只需要直接插入最后(只有num 个节点,同时新插入的节点的id是num+1) 暂时不考虑删除节点的文件空间回收。 打开文件是要注意打开模式,r+模式可以才可以随意用fseek()定位之后,读或写。 fseek()和fread()和fwrite()是用于二进制打开的文件,如果文本模式打开,可能出现问题,如:覆盖。 #include #include #include #include #define T 3 /b+树的度数 #define KeyType int #de

    3、fine Pointer int /节点结构体 typedef struct BPNode unsigned int id;/记录这个节点在文件的中的编号 unsigned int n; /记录这个节点有多少个关键字 int leaf; /判断是否为页节点 KeyType key2*T;/关键字(及对应每个孩子节点的中关键字最小的关键字) Pointer child2*T;/指针,记录每个孩子在文件的第几个位置 Pointer next;/指针,记录下一个兄弟 BPNode,*P_BPNode; /树的结构体 typedef struct BPTree P_BPNode root; unsig

    4、ned int locate;/记录根节点的在文件中的标号,即id unsigned int num; /记录更有多少个节点 char name100; /用于存储B+树的节点文件的名字 FILE *fp; /打开写入name文件时,使用 int start; /最小的数据所在的叶节点 BPTree,*P_BPTree; BPTree indexBPTree; /全局变量,b+树 int writeNode(P_BPNode w) fseek(indexBPTree.fp, sizeof(BPNode)*(w-id - 1) + 2*sizeof(int), SEEK_SET); fwrite

    5、(w, sizeof(BPNode),1,indexBPTree.fp); return 0; int readNode(P_BPNode r, Pointer id) fseek(indexBPTree.fp, (sizeof(BPNode)*(id - 1) + 2*sizeof(int), SEEK_SET); fread(r, (sizeof(BPNode),1,indexBPTree.fp); return 0; int pNode(P_BPNode n); int createIndexBPTree (char *tableName, char *attr) /创建B+树,并进行相

    6、应的初始化,B+树的结构体是一个全局变量。 P_BPNode root; indexBPTree.root = (P_BPNode)malloc(sizeof(BPNode); indexBPTree.num = 1; indexBPTree.start = 1; memcpy(indexBPTree.name, .table, sizeof(.table); strcat(indexBPTree.name, tableName); strcat(indexBPTree.name, .); strcat(indexBPTree.name, attr); puts(indexBPTree.nam

    7、e); root = indexBPTree.root; root-n = 0; root-leaf = 1; root-next = -1; root-id = 1; indexBPTree.locate = 1; indexBPTree.fp = fopen(indexBPTree.name, wb); fwrite(&indexBPTree.num, sizeof(int),1,indexBPTree.fp); fwrite(&indexBPTree.locate, sizeof(int),1,indexBPTree.fp); writeNode(root); fclose(indexB

    8、PTree.fp); /* printf(原始:%dn, indexBPTree.root-next); memset(indexBPTree.root,0,sizeof(BPNode); printf(memset后:%dn, indexBPTree.root-next); indexBPTree.fp = fopen(indexBPTree.name,r); fread(indexBPTree.root, sizeof(BPNode),1,indexBPTree.fp); fclose(indexBPTree.fp); printf(读取文件后:%dn, indexBPTree.root-

    9、next); */ free(root); indexBPTree.root = NULL; return 0; int splitBPNode (P_BPNode p, P_BPNode c, int i) /节点的分裂,要求p节点至少还能插入一个节点,c节点是满的,即n为2*T; int j; P_BPNode b; b = (P_BPNode)malloc(sizeof(BPNode); b-leaf = c-leaf; b-n = T; b-id = indexBPTree.num+1; /为b赋值id号,用于表示该节点,同时id号就是这个节点在文件的位置 b-next = c-nex

    10、t; /为b的next赋值,即原来的c节点的next /将c节点的后半部分关键字复制给b for (j = 0; j keyj = c-keyj+T; b-childj = c-childj+T; /至此b节点的对应元素已经建立好了,但还需要写入文件 indexBPTree.num+; c-n = T; /c节点的关键字数目减半 c-next = b-id; /将p节点的i之后的节点后移 for (j = p-n - 1; j i; j-) p-keyj+1 = p-keyj; p-childj+1 = p-childj; /将b节点插入p中 p-keyi+1 = b-key0; p-chil

    11、di+1 = b-id; p-n+; /p关键字个数加一 /写入p writeNode(p); writeNode(c); writeNode(b); free(b); return 0; /splitBPNode int insertBPNodeNotFull(P_BPNode s, KeyType k, unsigned int id) /插入,要求s节点不是满的 int i = s-n-1; if (s-leaf) /叶节点,找的合适的位置 while (i = 0 & s-keyi k) s-keyi+1 = s-keyi; s-childi+1 = s-childi; i-; s-k

    12、eyi+1 = k; s-childi+1 = id; s-n+; writeNode(s); else P_BPNode tmp = (P_BPNode)malloc(sizeof(BPNode); while (i = 0 & s-keyi k) i-; if (i keyi = k; writeNode(s); readNode(tmp, s-childi); /读取对应的 if (tmp-n = 2*T) splitBPNode(s, tmp, i); if (k s-keyi+1) i+; readNode(tmp, s-childi); /重新读取,有待优化 insertBPNod

    13、eNotFull(tmp, k, id); free(tmp); return 0; Pointer equalSearch(P_BPTree tree, KeyType k) /等值查询,给出key值,查找对应的id,并返回。如果不存在该节点,返回一个负数int i; int result; P_BPNode r; r = tree-root; if (k key0) /比最小的节点小 return -1; P_BPNode tmp = (P_BPNode)malloc(sizeof(BPNode); while (1) i = r-n - 1; while (i = 0 & r-keyi

    14、k) i-; if (r-leaf) /是叶子,结束 break; readNode(tmp, r-childi); r = tmp; /while if (r-keyi childi; free(tmp); tmp = NULL; return result; /equalSearch int rangeSearch (P_BPTree tree, KeyType low, KeyType high) /范围查找,key值大于等于low,小于等于high。返回范围内的个数, unsigned int i; P_BPNode r = tree-root; Pointer *result; P_

    15、BPNode tmp = (P_BPNode)malloc(sizeof(BPNode); if (high low) /low = high才有能有结果 return 0; if (high key0) return 0; if (low key0) low = r-key0; while (1) i = r-n - 1; while (i = 0 & r-keyi low) i-; if (r-leaf) /是叶子,结束 break; readNode(tmp, r-childi); r = tmp; /while if (r-keyi low) i+; unsigned int num=

    16、100; result = (Pointer *)malloc(sizeof(Pointer)*num); unsigned int j = 0; while (1) for (; i n & r-keyi = num) num += 100; realloc(result, sizeof(Pointer)*num); resultj+ = r-childi; / printf(sid:%d iid: %d id:%dn, r-keyi,r-id, r-childi); if (i n | r-next next); r = tmp; i = 0; /while free(tmp); tmp

    17、= NULL; return j; /rangeSearch int insertKeyInBPTree (P_BPTree tree, KeyType k, Pointer id) /向树中插入节点 P_BPNode r = tree-root; if (equalSearch(tree, k) 0) printf(元素已存在!); return -1; if (tree-root-n = 2*T) /根节点满了,重新分配根节点,并进行初始化 P_BPNode s = (P_BPNode)malloc(sizeof(BPNode); s-leaf = 0; s-n = 1; s-key0 =

    18、 r-key0; s-child0 = r-id; s-id = tree-num + 1; s-next = -1; /将新的根写入磁盘 writeNode(s); tree-num+; writeNode(r); splitBPNode (s, r, 0); /根变为s,所以将新根copy到tree-root指针所指向的内存。(tree-root将一直指向一片开辟了的内存,且时刻保存树根的整个节点) memcpy(tree-root, s, sizeof(BPNode); tree-locate = s-id; insertBPNodeNotFull(s, k, id); free(s);

    19、 /释放内存 else insertBPNodeNotFull(r, k, id); return 0; /insertBPNode int initIndexBPTree(char *tableName, char *attr) /初始化BPTree,打开相应文件,fp记录;为root分配内存可以存储一个节点的内存,并读入根节点 indexBPTree.root = (P_BPNode)malloc(sizeof(BPNode); indexBPTree.start = 1; memcpy(indexBPTree.name, .table, sizeof(.table); strcat(in

    20、dexBPTree.name, tableName); strcat(indexBPTree.name, .); strcat(indexBPTree.name, attr); indexBPTree.fp = fopen(indexBPTree.name, rb+); fread(&indexBPTree.num,sizeof(int),1, indexBPTree.fp); fread(&indexBPTree.locate,sizeof(int),1,indexBPTree.fp); readNode(indexBPTree.root, indexBPTree.locate); retu

    21、rn 0; int endBPTree() /将建立的树结束 fseek(indexBPTree.fp, 0, SEEK_SET); fwrite(&indexBPTree.num, sizeof(int),1,indexBPTree.fp); fwrite(&indexBPTree.locate, sizeof(int),1,indexBPTree.fp); free(indexBPTree.root); fclose(indexBPTree.fp); return 0; int pNode(P_BPNode n) /输出节点 printf(%s id:%d next:%d 个数:%dn ,

    22、n-leaf?是叶节点:不是叶节点, n-id, n-next, n-n); for(unsigned int i = 0; i n; i+) printf( key%d:%dt,i,n-keyi); puts(); for(i = 0; i n; i+) printf(child%d:%dt,i,n-childi); puts(); return 0; /pNode int replaceKeyInBPTree(P_BPTree tree, KeyType oldkey, KeyType newkey) /将oldkey替换为newkey P_BPNode r = tree-root; in

    23、t i; P_BPNode tmp = (P_BPNode)malloc(sizeof(BPNode); while (1) i = r-n - 1; while (i = 0 & r-keyi oldkey) i-; if (r-keyi = oldkey) r-keyi = newkey; writeNode(r); if (r-leaf) break; readNode(tmp, r-childi); r = tmp; free(tmp); return 0; int adjustToDel(P_BPNode p, P_BPNode x, unsigned int i) /p指向x的父节

    24、点,i指的是,x是p的下标 unsigned int j; P_BPNode left = NULL; P_BPNode right = NULL; P_BPNode tmp = (P_BPNode)malloc(sizeof(BPNode); if (i 0 ) /x有左兄弟 readNode(tmp, p-childi-1); left = tmp; if (left-n T) for (j = x-n; j 0; j-) x-keyj = x-keyj-1; x-childj = x-childj-1; x-n+; x-key0 = left-keyleft-n-1; x-child0

    25、= left-childleft-n-1; writeNode(x); left-n-; writeNode(left); p-keyi = x-key0; writeNode(p); return 0; /if if (i n - 1) /x有又兄弟 readNode(tmp, p-childi+1); right = tmp; left = NULL; if (right-n T) x-keyx-n = right-key0; x-childx-n = right-child0; x-n+; writeNode(x); for (j = 0; j n-1; j+) right-keyj =

    26、 right-keyj+1; right-childj = right-childj+1; right-n-; writeNode(right); p-keyi+1 = right-key0; writeNode(p); return 0; if (left = tmp) for (j = 0; j keyT+j = x-keyj; left-childT+j = x-childj; left-n += T; left-next = x-next; writeNode(left); for (j = i; j n - 1; j+) p-keyj = p-keyj+1; p-childj = p

    27、-childj+1; p-n-; writeNode(p); memcpy(x, left, sizeof(BPNode); else for (j = 0; j keyT+j = right-keyj; x-childT+j = right-childj; x-n += T; x-next = right-next; writeNode(x); for (j = i+1; j n -1; j+) p-keyj = p-keyj+1; p-childj = p-childj+1; p-n-; writeNode(p); free(tmp); left = right = tmp = NULL; return 0; /调用这个函数是,参数节点p,必须满足相应的要求: /如果p是根节点且是叶子节点,则没有要求 /如果p是根节点(非叶),则p节点的子节点个数不小于2(B+树


    注意事项

    本文(B+树的代码实现.docx)为本站会员主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1

    收起
    展开