B树
/************************************************
*作者:陈新
*时间: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树的更多相关文章
- B树——算法导论(25)
B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...
- ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单
前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- HDU1671——前缀树的一点感触
题目http://acm.hdu.edu.cn/showproblem.php?pid=1671 题目本身不难,一棵前缀树OK,但是前两次提交都没有成功. 第一次Memory Limit Exceed ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- bzoj3207--Hash+主席树
题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...
- bzoj1901--树状数组套主席树
树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...
- bzoj3932--可持久化线段树
题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...
- jquery-treegrid树状表格的使用(.Net平台)
上一篇介绍了DataTable,这一篇在DT的基础之上再使用jquery的一款插件:treegrid,官网地址:http://maxazan.github.io/jquery-treegrid/ 一. ...
随机推荐
- 我为开源做贡献,网页正文提取——Html2Article
为什么要做正文提取 一般做舆情分析,都会涉及到网页正文内容提取.对于分析而言,有价值的信息是正文部分,大多数情况下,为了便于分析,需要将网页中和正文不相干的部分给剔除.可以说正文提取的好坏,直接影响了 ...
- Kanzi Q&A
Q:为什么我的kanzi studio安装完后无法编译apk? A:请安装jdk,并设置环境变量,并更新thirdpartsdk. Q:为什么使用路径无法读取到列表listbox内的列表项? A:列表 ...
- VS.Net 2015 Update3 学习(2) jquery-form, jquery-validation,jquery-validation-unobtrusive一起用
我觉DataAnnotations非常酷的一个功能.但是教程中的@ajaxform的却不怎么优雅,需要全局的onSucces等函数.因此我使用jquery-form做ajax提交. function ...
- 重写toString()方法来描述一个类
package com.zch.test; /* toString方法以及重写toString方法 toString方法是一个自我描述方法 方法本身返回的是该对象的实现类的 类名 + @ + hash ...
- Android 6.0权限改变
对于6.0以下的权限及在安装的时候,根据权限声明产生一个权限列表,用户只有在同意之后才能完成app的安装,造成了我们想要使用某个app,就要默默忍受其一些不必要的权限(比如是个app都要访问通讯录.短 ...
- centos 忘记密码
装了个 centos 6.8 安装的时候 要输入 新用户和密码 用 新的用户密码 进去后 各种没权限 重新修改 root 密码 一切OK 步骤 1.重新启动Centos,在启动过程中,长按“ ...
- DFA敏感词过滤
import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.ArrayList; ...
- CentOS 程序开机自启动方法总结
1.把启动程序的命令添加到/etc/rc.d/rc.local文件中 CentOS系统下管理开机自启动的配置文件是/etc/rc.d/rc.local,所以只需编辑这个文件,在里面加入相应的启动命令即 ...
- 直播中用到的一些js
1.document.hidden ,<高级三>中详细解释 25.2 Page Visibility API不知道用户是不是正在与页面交互,这是困扰广大Web 开发人员的一个主要问题.如果 ...
- [HTML/HTML5]8 使用表格
8.1 创建基本的表格结构 8.1.1 表格结构 HTML表格包含4种基本元素: table:在HTML中table元素是一个容器,其中包含用于创建表格的其它的元素: tr:表示表格中的行,开始标 ...