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/ 一. ...
随机推荐
- Windows 服务快捷启动命令
gpedit.msc-----组策略sndrec32-----录音机nslookup----- ip地址侦测器explorer------ 打开资源管理器logoff-------注销命令tsshut ...
- Java开发中经典的小实例-(swich(){case:参数break;default: break;})
import java.util.Scanner;public class Test6 { public static void main(String[] args) { // ...
- python非递归全排列
刚刚开始学习python,按照廖雪峰的网站看的,当前看到了函数这一节.结合数组操作,写了个非递归的全排列生成.原理是插入法,也就是在一个有n个元素的已有排列中,后加入的元素,依次在前,中,后的每一个位 ...
- hadoop修改MR的提交的代码程序的副本数
hadoop修改MR的提交的代码程序的副本数 Under-Replicated Blocks的数量很多,有7万多个.hadoop fsck -blocks 检查发现有很多replica missing ...
- Markdown中插入数学公式的方法
Markdown中插入数学公式的方法 文章来源:http://blog.csdn.net/xiahouzuoxin/article/details/26478179 自从使用Markdown以来,就开 ...
- Git_1基础操作,从安装到提交完成(windows)
github地址:https://github.com/zhangsai521314/Git 1:安装Git Bash(https://git-scm.com/),安装一路NEXT. 2:目录架构: ...
- Linux Oracle 转换编码格式
[oracle@gpdb ~]$ sqlplus /nolog SQL> conn /as sysdba; SQL>select userenv('language') from dual ...
- 慕课网__css3__3D
- 撤销git reset soft head操作
一不小心在eclipse的git库中执行了Reset Soft(HEAD ONLY)操作,不料界面中竟然没有找到撤销方法(于是心中五味俱全,经过一番折腾,无果还是回归Git本身),最终通过命令行,很快 ...
- centos7 升级内核到最新版本
centos7 从问世以来,官网提供的镜像始终是3.10 版本,该版本最大的一个问题是对硬件驱动(尤其是无线网卡)的支持不是很好,本人亲测>5种机型,无线网卡均无法正常使用,如果是非主流机型,手 ...