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

先上代码

 #include "000库函数.h"

 #define MAXSIZE 100//存储空间

 #define m 3//B树的阶
#define N 17//数据元素的个数
#define MAX 5//字符串的最大长度 struct BTree
{
int keynum;//节点中关键字的个数 即节点大小
BTree *parent;//指向双亲的指针
struct Node//节点向量类型
{
int key;//关键字向量
BTree *ptr;//子树指针向量
int recptr;//记录指针向量
};
Node node[m + ];//0号单元未使用
}; struct Result{
BTree *pt;//指向找到的节点
int i;//在节点中的关键字序号
int tag;//查找成功与否
}; int Search(BTree *p, int elem) {//p.node[i].key<=elem<p.node[i+1].key
int j;
for (int i = ; i < p->keynum; ++i)
if (p->node[i].key <= elem)
j = i;
return j;
} //查找B树中是否存在该数
/*关键字应该插在指针pt所指节点中的第i和第i+1个关键字之间*/
Result* SearchBTree(BTree *T, int elem) {
BTree *p, *q;
p = T;
q = NULL;
int find = false;
Result *r = new Result;
int i = ;
while (p && !find) {
i = Search(p, elem);//p.node[i].key<=elem<p.node[i+1].key
if (i > && p->node[i].key == elem)//查找到了关键字
find = true;
else {
q = p;
p = p->node[i].ptr;
}
}
r->i = i;
if(find){//查找成功
r->pt = p;
r->tag = ;
}
else {//查找不成功,返回elem的插入位置的信息
r->pt = q;
r->tag = ;
}
return r;
} /* 将r->key、r和ap分别插入到q->key[i+1]、q->recptr[i+1]和q->ptr[i+1]中 */
int Insert(BTree* &pt, int n, int rx, BTree *ap) {
for (int i = pt->keynum; i > n; --i)//空出pt->node[n+1]
pt->node[i + ] = pt->node[i];//向后挪,腾出位置来
pt->node[n + ].key = rx;
pt->node[n + ].ptr = ap;
pt->node[n + ].recptr = rx;
pt->keynum++;
return true;
} /* 将结点q分裂成两个结点,前一半保留,后一半移入新生结点ap */
int split(BTree* &pt, BTree* &ap) {
int s = (m + ) / ;
ap = new BTree;//生成新的节点ap
ap->node[].ptr = pt->node[s].ptr;//后一半移入ap中
for (int i = s + ; i < m; ++i) {
ap->node[i - s] = pt->node[i];
if (ap->node[i - s].ptr)
ap->node[i - s].ptr->parent = ap;
}
ap->keynum = m - s;
ap->parent = pt->parent;
pt->keynum = s - ;/* q的前一半保留,修改keynum */ return true;
} /* 生成含信息(T,r,ap)的新的根结点&T,原T和ap为子树指针 */
int NewRoot(BTree *T, int key, BTree *ap) {
BTree *p = new BTree;
p->node[].ptr = T;
T = p;
if (T->node[].ptr)
T->node[].ptr->parent = T;
T->parent = NULL;
T->keynum = ;
T->node[].key = key;
T->node[].recptr = key;
T->node[].ptr = ap;
if (T->node[].ptr)
T->node[].ptr->parent = T; return true;
} /* 在m阶B树T上结点*q的key[i]与key[i+1]之间插入关键字K的指针r。若引起 */
/* 结点过大,则沿双亲链进行必要的结点分裂调整,使T仍是m阶B树。 */
int InsertBTree(BTree* &T, int elem, BTree *pt, int n) {
BTree *ap;
ap = new BTree;
bool finished = false;
int s, rx;
rx = elem;
while (pt && !finished) {
Insert(pt, n, rx, ap);// 将r->key、r和ap分别插入到q->key[i+1]、q->recptr[n+1]和q->ptr[n+1]中 */
if (pt->keynum < m)
finished = true;//插入成功
else {//对节点进行分裂
s = (m + ) / ;
rx = pt->node[s].recptr;
split(pt, ap);/* 将q->key[s+1..m],q->ptr[s..m]和q->recptr[s+1..m]移入新结点*ap */
pt = pt->parent;
if (pt)
n = Search(pt, elem);//在双亲结点中*q中查找rx->key的插入位置
}
}
if (!finished)/* T是空树(参数q初值为NULL)或根结点已分裂为结点*q和*ap */
NewRoot(T, rx, ap);/* 生成含信息(T,rx,ap)的新的根结点*T,原T和ap为子树指针 */ return true;
} int T034()
{
int r[N] = { ,,,,,,,,,,,,,,,, };
BTree *T = new BTree;
T = NULL;
Result *s;
for (int i = ; i < N; i++)
{
s = SearchBTree(T, r[i]);
if (!s->tag)
InsertBTree(T, r[i], s->pt, s->i);
}
printf("\n请输入待查找记录的关键字: ");
int a;
scanf("%d", &a);
s = SearchBTree(T, a);
if (s->tag)
printf("(%d)", (s->pt)->node[a].key);
else
printf("没找到");
printf("\n"); return ;
}

数据结构【查找】—B树的更多相关文章

  1. D&F学数据结构系列——B树(B-树和B+树)介绍

    B树 定义:一棵B树T是具有如下性质的有根树: 1)每个节点X有以下域: a)n[x],当前存储在X节点中的关键字数, b)n[x]个关键字本身,以非降序存放,因此key1[x]<=key2[x ...

  2. 【经典数据结构】B树与B+树

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树 ...

  3. Linux 内核中的数据结构:基数树(radix tree)

    转自:https://www.cnblogs.com/wuchanming/p/3824990.html   基数(radix)树 Linux基数树(radix tree)是将指针与long整数键值相 ...

  4. 【经典数据结构】B树与B+树(转)

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树 ...

  5. 【经典数据结构】B树与B+树的解释

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 前面讲解了平衡查找树中的2-3树以及其实现红 ...

  6. 数据结构-PHP 线段树的实现

    转: 数据结构-PHP 线段树的实现 1.线段树介绍 线段树是基于区间的统计查询,线段树是一种 二叉搜索树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点.使用线段树可以快速的查 ...

  7. 数据结构之AVL树

    AVL树是高度平衡的而二叉树.它的特点是:AVL树中任何节点的两个子树的高度最大差别为1. 旋转 如果在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡.这种失去平衡的可以概括为4种姿态:LL ...

  8. 查找->静态查找表->次优查找(静态树表)

    文字描算 之前分析顺序查找和折半查找的算法性能都是在“等概率”的前提下进行的,但是如果有序表中各记录的查找概率不等呢?换句话说,概率不等的情况下,描述查找过程的判定树为何类二叉树,其查找性能最佳? 如 ...

  9. 数据结构与算法->树->2-3-4树的查找,添加,删除(Java)

    代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 目录 一. 2-3-4树的定义 二. 2-3-4树数据结构定义 三. 2-3-4树的可以得到 ...

  10. 数据结构实验7:实现二分查找、二叉排序(查找)树和AVL树

    实验7 学号:      姓名:     专业: 7.1实验目的 (1) 掌握顺序表的查找方法,尤其是二分查找方法. (2) 掌握二叉排序树的建立及查找. 查找是软件设计中的最常用的运算,查找所涉及到 ...

随机推荐

  1. 关于 Uboot 中有趣的 0xdeadbeef 填充

    在 Uboot 的 Start.S 中存在以下源码: .globl _start _start: b start_code ldr pc, _undefined_instruction ldr pc, ...

  2. Spark的核心RDD(Resilient Distributed Datasets弹性分布式数据集)

    Spark的核心RDD (Resilient Distributed Datasets弹性分布式数据集)  原文链接:http://www.cnblogs.com/yjd_hycf_space/p/7 ...

  3. 条件随机场conditional random field

    主要翻译自http://blog.echen.me/2012/01/03/introduction-to-conditional-random-fields/,原作者是MIT的大神,加入了一些我自己的 ...

  4. TCP&UDP&Socket讲解(上)

    这两天我将整理TCP&UDP&Socket,大约花大家10-15分钟之间,希望本篇文章让大家对TCP使用的理解提高一个层次. 建议大家拿出纸和笔,画一下!!! 一.TCP 1. TCP ...

  5. eclipse使用svn

    主干(trunk).分支(branch ).标记(tag) 用法示例 + 图解   以svn为例,git的master相当于trunk,dev分支相当于branches --------------- ...

  6. [PHP] PHP多进程处理tcp连接

    <?php if(($sock = socket_create(AF_INET, SOCK_STREAM, 0)) < 0) { echo "failed to create s ...

  7. CSS3动画属性:变形(transform)

    Transform字面上就是变形,改变的意思.在CSS3中transform主要包括以下几种:旋转rotate.扭曲skew.缩放scale和移动translate以及矩阵变形matrix. 语法 t ...

  8. window.requestAnimationFrame与Tween.js配合使用实现动画缓动效果

    window.requestAnimationFrame 概述 window.requestAnimationFrame()这个方法是用来在页面重绘之前,通知浏览器调用一个指定的函数,以满足开发者操作 ...

  9. Salesforce 大量数据部署的最佳实践

    本文参考自官方文档.原文链接 大量数据部署对Salesforce的影响 当用户需要在Salesforce中部署大量数据的时候,部署的过程往往会变慢.这时就需要架构师或开发者设计出更好的过程来提高大量数 ...

  10. Django 系统日志logging

    Django使用Python内建的logging模块去建造自己的系统日志的,如果你想详细了解这个模块的话,请自己去看python的说明文档,这里仅仅介绍Django中的日志系统. 日志配置包括四个部分 ...