/************************************************
*作者:陈新
*时间: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. 关于leetcode中链表中两数据相加的程序说明

    * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ ...

  2. Java开发中经典的小实例-(输入三个数字判断三角形类型)

    import java.util.Scanner;public class threeTest {    public static void main(String[] args) {       ...

  3. Ubuntu 修改 ssh 登录后的欢迎信息

    /etc/update-motd.d/90-updates-available cd /etc/update-motd.d/ vi 10-help-text 修改或者注释掉里面的内容 vi 90-up ...

  4. javascript字符转直接量和转义字符

    直接量: 你可以用单引号或者双引号来表示字符串的直接量.但是js的字符串必须是Unicode 字符序列. 转义字符: 主要用在字符串中,包涵控制字符,以及当前操作系统余元所不允许直接输入的字符. 转义 ...

  5. iOS runtime 初步学习

    注: 在Xocde5之后, 使用运行时方法需要进行2步设置1. 在Build Setting中搜索'msg', 设置'Strict Checking' 为 NO2. 使用需要导入头文件 #import ...

  6. winform异步系统升级—BackgroundWorker

    BackgroundWorker用法实例 自己的代码,就是要执行的代码写到dowork里,ProgressChanged事件是控制进度时用的,最后的Completed事件进度完成,也就是dowork里 ...

  7. Redis教程(二):String数据类型

    一.概述: 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等.在Redis中字符串类型 ...

  8. react 学习笔记

    1.Router 1.1 Histories React Router 是建立在 history 之上的.一个 history 知道如何去监听浏览器地址栏的变化, 并解析这个 URL 转化为 loca ...

  9. Dictionary<k,v>键值对的使用

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Dict ...

  10. Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式

    android线程池的理解,晚上在家无事 预习了一下android异步加载的例子,也学习到了一个很重要的东东 那就是线程池+缓存  下面看他们的理解.[size=1.8em]Handler+Runna ...