/************************************************
*作者:陈新
*时间:2014 6.3
*邮箱:cx2pirate@gmail.com
* **********************************************/ #ifndef _HEADER_BTREE_
#define _HEADER_BTREE_ #define N 5 //b-tree的度
#define TRUE 1
#define FALSE 0 typedef int BOOL;
typedef int Key; typedef struct btree_node{
int count;
BOOL is_leaf;
Key key[ * N - ];
struct btree_node *child[ * N];
}btree_node,*btree_node_ptr; typedef struct btree_root{
struct btree_node *node;
int height;
}btree_root,*btree_root_ptr; typedef struct btree_search_res{ //查询结果
btree_node *node;
int pos;
}btree_search_res; btree_root *btree_create();
btree_search_res btree_search(btree_node *node,Key key);
void btree_insert(btree_root *root,Key key);
void btree_delete(btree_root *root,Key key); #endif
 #include "btree.h"
#include <stdio.h>
#include <stdlib.h> //分配一个btree_node节点
btree_node *btree_node_alloc()
{
btree_node *node = (btree_node *)malloc(sizeof(btree_node));
if(node == NULL){
return NULL;
}
for(int i =;i < * N - ;i++){
node ->key[i] = ;
}
for(int i = ;i < * N;i++){
node ->child[i] = NULL;
}
node ->count = ;
node ->is_leaf = true;
return node;
} void btree_node_free(btree_node *node)
{
free(node);
} btree_root *btree_create()
{
btree_root *root = (btree_root *)malloc(sizeof(btree_root));
root ->node = btree_node_alloc();
return root;
} int btree_split_child(btree_node *parent,int pos,btree_node *child)
{
btree_node *new_child = btree_node_alloc();
if(new_child == NULL){
return -;
}
new_child ->is_leaf = child ->is_leaf;
new_child ->count = N - ; for(int i = ;i < N - ;i++){
new_child ->key[i] = child ->key[i + N];
}
if(!child ->is_leaf){
for(int i = ;i < N;i++){
new_child ->child[i] = child ->child[i + N];
}
}
child ->count = N - ; for(int i = parent ->count;i > pos;i--){
parent ->child[i + ] = parent ->child[i];
}
parent ->child[pos + ] = new_child; for(int i = parent ->count - ;i >= pos;i--){
parent ->key[i + ] = parent ->key[i];
}
parent ->key[pos] = child ->key[N - ];
parent ->count++; return ;
} void btree_insert_nonfull(btree_node *node,int key)
{
if(node ->is_leaf){ //case1:插入叶子节点
int pos = node ->count;
while(pos >= && key < node ->key[pos - ]){
node ->key[pos] = node ->key[pos - ];
pos--;
}
node ->key[pos] = key;
node ->count++;
}
else{ //case2:递归插入
int pos = node ->count;
while(pos > && key < node ->key[pos - ]){
pos--;
}
if(node ->child[pos] ->count == * N - ){
btree_split_child(node,pos,node ->child[pos]);//分裂
if(key > node ->key[pos]){ //选择新节点还是还是老节点
pos++;
}
}
btree_insert_nonfull(node ->child[pos],key);
}
} void btree_insert(btree_root *root,int key)
{
if(root ->node == NULL){
return;
} if(root ->node ->count == * N - ){ //分裂根节点
btree_node *old_root = root ->node;
root ->node = btree_node_alloc();
root ->node ->is_leaf = FALSE;
root ->node ->count = ;
root ->node ->child[] = old_root;
btree_split_child(root ->node,,old_root);
}
btree_insert_nonfull(root ->node,key);
}
/***************************************************
*删除部分
*
* ************************************************/
Key btree_maximum(btree_node *node)
{
btree_node *p = node;
while(!p ->is_leaf){
p = p ->child[p ->count];
}
return p ->key[p ->count - ];
} Key btree_minimum(btree_node *node)
{
btree_node *p = node;
while(!p ->is_leaf){
p = p ->child[];
}
return p ->key[];
} /*pos左右两个孩子都只有N - 1个关键字,
*把第pos个关键字,和两个孩子合并成一个
*新的节点
*/
void btree_merge(btree_node *parent,int pos)
{
btree_node *left_child = parent ->child[pos];
btree_node *right_child = parent ->child[pos + ]; left_child ->key[N - ] = parent ->key[pos];
//for(int i = 0;i < N;i++) //bug report
for(int i = ;i < N - ;i++) //竟然溢出覆盖了 ->child[0]
{
left_child ->key[N + i] = right_child ->key[i];
}
if(!right_child ->is_leaf){
for(int i = ;i < N;i++){
//left_child ->child[i] = right_child ->child[N + i]; //bug report
left_child ->child[N + i] = right_child ->child[i];
}
}
left_child ->count = * N - ; for(int i = pos + ;i < parent ->count;i++){
parent ->key[i - ] = parent ->key[i];
parent ->child[i] = parent ->child[i + ];
}
parent ->count--; btree_node_free(right_child);
} void shift_right_to_left(btree_node *parent,int pos)
{
btree_node *child = parent ->child[pos];
btree_node *right_child = parent ->child[pos + ]; child ->key[N - ] = parent ->key[pos];
parent ->key[pos] = right_child ->key[]; for(int i = ;i < right_child ->count - ;i++){
right_child ->key[i] = right_child ->key[i + ];
} if(!right_child ->is_leaf){
child ->child[N] = right_child ->child[];
for(int i = ;i < right_child ->count;i++){
right_child ->child[i] = right_child ->child[i + ];
}
} child ->count++;
right_child ->count--;
}
//
void shift_left_to_right(btree_node *parent,int pos)
{
btree_node *child = parent ->child[pos];
btree_node *left_child = parent ->child[pos - ]; //for(int i = 1;i <= child ->count;i++){ //bug report
for(int i = child ->count;i > ;i--){
child ->key[i] = child ->key[i - ];
}
//child ->key[0] = parent ->key[pos]; //bug report
//parent ->key[pos] = left_child ->key[left_child ->count - 1];
child ->key[] = parent ->key[pos - ];
parent ->key[pos - ] = left_child ->key[left_child ->count - ]; if(!left_child ->is_leaf){
for(int i = child ->count + ;i > ;i--){
child ->child[i] = child ->child[i - ];
}
child ->child[] = left_child ->child[left_child ->count];
} child ->count++;
left_child ->count--;
} //node至少含有N个关键字的删除情况
void btree_delete_noback(btree_node *node,Key key)
{
int pos = ;
while(pos < node ->count && node ->key[pos] < key){ //todo不存在的情况
pos++;
}
if(pos < node ->count && node ->key[pos] == key){ //case1 && case2
if(node ->is_leaf){ //case1
for(int i = pos;i < node ->count - ;i++){
node ->key[i] = node ->key[i + ];
}
node ->count--;
return;
} if(node ->child[pos] ->count >= N){ //case 2a
Key pre = btree_maximum(node ->child[pos]);
node ->key[pos] = pre;
btree_delete_noback(node ->child[pos],pre);
}
else if(node ->child[pos + ] ->count >= N){ //case 2b
Key suc = btree_minimum(node ->child[pos + ]);
node ->key[pos] = suc;
btree_delete_noback(node ->child[pos + ],suc);
}
else{ //case 2c
btree_merge(node,pos);
btree_delete_noback(node ->child[pos],key);
}
}
else{
if(node ->is_leaf){ //case1 特殊情况,不存在节点
return;
}
if(node ->child[pos] ->count == N - ){
btree_node *next = node ->child[pos];
if(pos > && node ->child[pos - ] ->count >= N){ //case 3a_1
shift_left_to_right(node,pos);
}
else if(pos < node ->count && node ->child[pos + ] ->count >= N){ //case 3a_2
shift_right_to_left(node,pos);
}
else if(pos > ){
btree_merge(node,pos - );
next = node ->child[pos - ];
}
else{
btree_merge(node,pos);
}
btree_delete_noback(next,key); //next may be wrong
}
}
} //删除时需要更新root的情况,参考算法导论
//case 2c 和 case 3b
BOOL is_root_change(btree_root *root)
{
return root ->node ->count == &&
root ->node ->child[] ->count == N - &&
root ->node ->child[] ->count == N - ;
} void btree_delete(btree_root *root,Key key)
{
if(is_root_change(root)){
btree_merge(root ->node,);
btree_node *old_root = root ->node;
root ->node = root ->node ->child[];
btree_node_free(old_root);
}
btree_delete_noback(root ->node,key);
} /****************************************************
*查找部分
*
* **************************************************/
//返回值...
btree_search_res btree_search(btree_node *node,int key)
{
int pos = ;
while(pos < node ->count && key > node ->key[pos]){
pos++;
}
if(pos < node ->count && key == node ->key[pos]){
return btree_search_res{node,pos}; //return node and pos
}
if(node ->is_leaf){
return btree_search_res{NULL,-};
}
return btree_search(node ->child[pos],key);
}

B树的更多相关文章

  1. B树——算法导论(25)

    B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...

  2. ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单

    前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...

  3. 再讲IQueryable<T>,揭开表达式树的神秘面纱

    接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...

  4. HDU1671——前缀树的一点感触

    题目http://acm.hdu.edu.cn/showproblem.php?pid=1671 题目本身不难,一棵前缀树OK,但是前两次提交都没有成功. 第一次Memory Limit Exceed ...

  5. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  6. [C#] C# 知识回顾 - 表达式树 Expression Trees

    C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...

  7. bzoj3207--Hash+主席树

    题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...

  8. bzoj1901--树状数组套主席树

    树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...

  9. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  10. jquery-treegrid树状表格的使用(.Net平台)

    上一篇介绍了DataTable,这一篇在DT的基础之上再使用jquery的一款插件:treegrid,官网地址:http://maxazan.github.io/jquery-treegrid/ 一. ...

随机推荐

  1. pip和easy_install更换使用国内源

    因为论文原因,需要使用python安装一些自然语言库,但是使用pip或easy_install安装包时,总是超时(中国特色搞得事:-D),没有办法,上网查资料解决问题~~,在网上找到的方法都是说更换国 ...

  2. C#知识点总结系列:5、CLR的组成和运转

    clr基本 CLR(Common Language Runtime)是一个可由多种编程语言使用的“运行时”.(例如:c#,c++/cli,vb,f#,ironpython,ironruby,il... ...

  3. git本地提交到远程仓库命令

    创建好远程仓库,然后要从本地上传代码到远程仓库: 1.git init 初始化git本地仓库 2. git add 添加到暂存区 3. git commit -am "提交备注" ...

  4. github项目配置

    准备工作: 下载一个git:  https://git-scm.com/downloads 1.登陆到github 登陆地址:https://github.com/login 2.创建新项目 3.配置 ...

  5. C++ STL vector容器学习

    STL(Standard Template Library)标准模板库是C++最重要的组成部分,它提供了一组表示容器.迭代器.函数对象和算法的模板.其中容器是存储类型相同的数据的结构(如vector, ...

  6. eslintrc配置翻译

    { "env": { "browser": true, "node": true, "commonjs": true } ...

  7. neatbean 8+版本 配置

    //更改代码行距 打开C:\Users\{yourname}\AppData\Roaming\NetBeans\7.3.1\config\Editors\Preferences,用文本编辑器打开 or ...

  8. html5对密码加密

    今天找了几个关于对html5的密码加密的方法,仅供参考 1.base64加密:在页面中引入base64.js文件,调用方法为: <html> <head> <meta c ...

  9. 03-方法ppt动手动脑问题及课后实验性问题总结

    一.如何不使用static来进行调用函数? 1.自己定义的不需要都是static,但是要在主函数中调用就需要static了,因为main是静态 的,在类加载时就加载了.如果想用又不加可以吧自己写的方法 ...

  10. Oracle 乱码

    导入DMP之后 ..... 1.Oacle数据库表中数据乱码 请检查导出DMP的ORACLE数据库编码设置 修改ORACLE编码与原DMP导出编码一致 select userenv('language ...