100分求B-树的资料或清华出的数据结构电子版

pzl 2003-11-05 09:59:29
急,大家帮忙啦!
...全文
26 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
rockaka 2003-11-25
  • 打赏
  • 举报
回复
信已经受到!谢谢
pzl 2003-11-21
  • 打赏
  • 举报
回复
信收到了,多谢你呀,我再开一个给分帖,过来拿分!
tudou614 2003-11-20
  • 打赏
  • 举报
回复
还是买书吧,其实很便宜的,

顺便推荐一本好书《。。。。。》高一凡 编(西电)

书是绿皮的,适合我这种自学的人!!

rockaka 2003-11-20
  • 打赏
  • 举报
回复
搂主,收到后能给我一份吗?我也找了好久,谢谢!rockaka@163.com
fryboy 2003-11-20
  • 打赏
  • 举报
回复
关注~
pzl 2003-11-20
  • 打赏
  • 举报
回复
兄弟,我的EMAIL:peizelong@sohu.com
多谢你呀!
apogeecsj 2003-11-19
  • 打赏
  • 举报
回复
/*
* 合并一个节点的某个键对应的两个子树
*/
void JoinNode(btree t, int d)
{
btree l,r;
int i,j;
l = t->p[d];
r = t->p[d+1];
i = l->d;
/* 把这个键下移到它的左子树 */
l->k[i] = t->k[d];
l->v[i] = t->v[d];
/* 把右子树中的所有键值和子树转移到左子树 */
l->p[i+1] = r->p[0];
for (j=r->d-1,i+=r->d; j >= 0 ; j--,i--) {
l->k[i] = r->k[j];
l->v[i] = r->v[j];
l->p[i+1] = r->p[j+1];
}
l->d += r->d+1;
/* 释放右子树的节点 */
FreeNode(r);
/* 把这个键右边的键和对应的右子树左移 */
for (i=d; i < t->d-1; i++) {
t->k[i] = t->k[i+1];
t->v[i] = t->v[i+1];
t->p[i+1] = t->p[i+2];
}
t->d--;
}
/*
* 从一个键的右子树向左子树转移一些键,使两个子树平衡
*/
void MoveLeft(btree t, int d)
{
btree l,r;
int m; /* 应转移的键的数目 */
int i,j;
l = t->p[d];
r = t->p[d+1];
m = (r->d - l->d)/2;
i = l->d;
/* 把这个键下移到它的左子树 */
l->k[i] = t->k[d];
l->v[i] = t->v[d];
/* 把右子树的最左子树转移成左子树的最右子树 */
l->p[i+1] = r->p[0];
/* 从右子树向左子树移动 m-1 个键+子树对 */
for (j=m-2,i+=m-1; j >= 0; j--,i--) {
l->k[i] = r->k[j];
l->v[i] = r->v[j];
l->p[i+1] = r->p[j+1];
}
/* 把右子树的最左键提升到这个键的位置上 */
t->k[d] = r->k[m-1];
t->v[d] = r->v[m-1];
/* 把右子树中的所有键值和子树左移 m 个位置 */
r->p[0] = r->p[m];
for (i=0; i<r->d-m; i++) {
r->k[i] = r->k[i+m];
r->v[i] = r->v[i+m];
r->p[i+1] = r->p[i+1+m];
}
l->d+=m;
r->d-=m;
}
/*
* 从一个键的左子树向右子树转移一些键,使两个子树平衡
*/
void MoveRight(btree t, int d)
{
btree l,r;
int m; /* 应转移的键的数目 */
int i,j;
l = t->p[d];
r = t->p[d+1];
m = (l->d - r->d)/2;
/* 把右子树中的所有键值和子树右移 m 个位置 */
for (i=r->d-1; i>=0; i--) {
r->k[i+m] = r->k[i];
r->v[i+m] = r->v[i];
r->p[i+1+m] = r->p[i+1];
}
r->p[m]=r->p[0];
/* 把这个键下移到它的右子树 */
r->k[m-1] = t->k[d];
r->v[m-1] = t->v[d];
/* 把左子树的最右子树转移成右子树的最左子树 */
r->p[m-1] = l->p[l->d];
/* 从左子树向右子树移动 m-1 个键+子树对 */
for (i=l->d-1,j=m-2; j>=0; j--,i--) {
r->k[j] = l->k[i];
r->v[j] = l->v[i];
r->p[j] = l->p[i];
}
/* 把左子树的最右键提升到这个键的位置上 */
t->k[d] = l->k[i];
t->v[d] = l->v[i];
l->d-=m;
r->d+=m;
}
apogeecsj 2003-11-19
  • 打赏
  • 举报
回复
btree delete(typekey key, btree t)
{

flag = 0;
InternalDelete(key, t);
/* 检查在根节点上的减少 */
if (t->d == 0) {/* 根节点的子节点合并之后,根节点为空 */
btree_height--;
return(FreeNode(t));
}
return t;
}

void InternalDelete(typekey key, btree t)
{
int i;
btree l,r;
if (t == NULL) {
Error(0,key); /* 在整个树中未找到要删除的键 */
return;
}
for (i=0; i < t->d && key > t->k[i]; i++);
if (i < t->d && key == t->k[i]) { /* 找到要删除的键 */
if (t->v[i] != NULL)
free(t->v[i]); /* 释放这个节点包含的值 */
if (t->p[0] == NULL) { /* 有子树为空则这个键位于叶子节点 */
/* 把所有大于要插入的键值的键左移 */
for(; i < t->d-1; i++) {
t->k[i] = t->k[i+1];
t->v[i] = t->v[i+1];
}
t->d--;
flag = 1;
return;
} else { /* 这个键位于非叶节点 */
l = t->p[i];
r = t->p[i+1];
if (l->d >= r->d) {
/* 找到前驱节点 */
r = l;
while (r->p[0] != NULL)
r = r->p[r->d];
t->k[i]=r->k[r->d-1];
t->v[i]=r->v[r->d-1];
InternalDelete(r->k[r->d-1],l);
} else {
/* 找到后继节点 */
l = r;
while (l->p[0] != NULL)
l = l->p[0];
t->k[i]=l->k[0];
t->v[i]=l->v[0];
InternalDelete(l->k[0],r);
}
}
}
else /* 在当前节点中未找到要删除的键 */
InternalDelete(key,t->p[i]);
/* 调整平衡 */
if (flag == 1) {
if (i == t->d)
i--;
l = t->p[i];
r = t->p[i+1];
if (l->d < M && r->d > M)
MoveLeft(t,i);
else if(l->d > M && r->d < M)
MoveRight(t,i);
else if (l->d < M || r->d < M) {
JoinNode(t,i);
flag = 1;
return;
}
}
flag = 0;
}
/*
apogeecsj 2003-11-19
  • 打赏
  • 举报
回复
我有,这里不能连续回三次,所以变这样了,你留个email。
pzl 2003-11-19
  • 打赏
  • 举报
回复
上面的例程不全呀,少了好几个函数,谁有全的吗?分不够我再加!
apogeecsj 2003-11-11
  • 打赏
  • 举报
回复
/*
* 把一个键和对应的右子树插入一个节点中
*/
void InsInNode(btree t, int d)
{
int i;
/* 把所有大于要插入的键值的键和对应的右子树右移 */
for(i = t->d; i > d; i--){
t->k[i] = t->k[i-1];
t->v[i] = t->v[i-1];
t->p[i+1] = t->p[i];
}
/* 插入键和右子树 */
t->d++;
t->k[i] = InsKey;
t->p[i+1] = NewTree;
t->v[i] = Value;
}
/*
* 前件是要插入一个键和对应的右子树,但本节点已经满
* 导致分割这个节点,并向上层返回一个要插入键和对应的右子树
*/
void SplitNode(btree t, int d)
{
int i;
btree temp;
typekey temp_k;
char *temp_v;
/* 建立新节点 */
temp = (btree)malloc(sizeof(node));
if (d > M) { /* 要插入当前节点的右半部分 */
/* 把 M-1 个键值+子树对转移到新节点中 */
for(i=M-2; i>=0; i--) {
temp->k[i] = t->k[i+(M+1)];
temp->v[i] = t->v[i+(M+1)];
temp->p[i+1] = t->p[i+1+(M+1)];
}
/* 把节点的最右子树转移成新节点的最左子树 */
temp->p[0] = t->p[M+1];
/* 保存要插入上层节点的键和值 */
temp_k = t->k[M];
temp_v = t->v[M];
t->d = M;
temp->d = M-1;
InsInNode(temp, d-(M+1));
} else {
/* 把 M 个键值+子树对转移到新节点中 */
for(i=M-1; i>=0; i--) {
temp->k[i] = t->k[i+M];
temp->v[i] = t->v[i+M];
temp->p[i+1] = t->p[i+1+M];
}
if (d == M) { /* 要插入当前节点的正中间 */
/* 把要插入的子树作为新节点的最左子树 */
temp->p[0] = NewTree;
t->d = M;
temp->d = M;
NewTree = temp;
return;
} else { /* (d<M) 要插入当前节点的左半部分 */
/* 把节点的最右子树转移成新节点的最左子树 */
temp->p[0] = t->p[M];
/* 保存要插入上层节点的键和值 */
temp_k = t->k[M-1];
temp_v = t->v[M-1];
t->d = M-1;
temp->d = M;
InsInNode(t, d);
}
}
InsKey = temp_k;
Value = temp_v;
NewTree = temp;
}

btree delete(typekey key, btree t)
{

flag = 0;
InternalDelete(key, t);
/* 检查在根节点上的减少 */
if (t->d == 0) {/* 根节点的子节点合并之后,根节点为空 */
btree_height--;
return(FreeNode(t));
}
return t;
}
apogeecsj 2003-11-11
  • 打赏
  • 举报
回复
/* btrees.c */
#include <stdlib.h>
#include <stdio.h>
#include "btrees.h"

btree search(typekey, btree);
btree insert(typekey,btree);
btree delete(typekey,btree);
int height(btree);
int count(btree);
btree deltree(btree);

static void InternalInsert(typekey, btree);
static void InsInNode(btree, int);
static void SplitNode(btree, int);
static btree NewNode(typekey, btree, btree);
static void InternalDelete(typekey, btree);
static btree FreeNode(btree);
static void JoinNode(btree, int);
static void MoveLeft(btree t, int);
static void MoveRight(btree t, int);
static btree delall(btree);
static void Error(int,typekey);

static int flag; /* 节点增减标志 */
static int btree_height = 0; /* 多路树的高度 */
static typekey InsKey; /* 要插入的键 */
static btree NewTree; /* 在节点分割的时候指向新建的节点 */
static char * Value; /* 插入键时存放它对应的值 */

btree search(typekey key, btree t)
{
int i;
while (t != NULL){
for (i=0; i < t->d && key > t->k[i] ; i++);
if (i < t->d && key == t->k[i]){
btree_disp = i;
return t;
}
t = t->p[i];
}
return NULL;
}

btree insert(typekey key, btree t)
{
flag = 0;
InternalInsert(key, t);
/* 检查在根节点上的增长 */
if (flag == 1) { /* 根节点满之后,它被分割成两个半满节点 */
btree_height++;
return(NewNode(InsKey, t, NewTree)); /* 树的高度增加 */
}
return(t);
}

void InternalInsert(typekey key, btree t)
{
int i;
if (t == NULL){ /* 到达了树的底部: 指出要做的插入 */
NewTree = NULL; /* 这个键没有对应的子树 */
InsKey = key; /* 导致底层的叶子节点增加键值+空子树对 */
Value = NULL; /* 这个键没有对应的值 */
flag = 1; /* 指示上层节点把返回的键插入其中 */
} else {
for (i=0; i<t->d && key>t->k[i]; i++);
if (i<t->d && key == t->k[i])
Error(1,key); /* 键已经在树中 */
else { /* t->k[i] > key */
InternalInsert(key, t->p[i]); /* 插入到当前键的左子树或节点的最右子树中 */
if (flag == 1) { /* 有新键要插入到当前节点中 */
if (t->d < 2*M) {/* 当前节点未满 */
InsInNode(t, i); /* 把键值+子树对插入当前节点中 */
flag = 0;
} else {
/* 当前节点已满必须被分割 */
SplitNode(t, i);
/* 继续指示上层节点把返回的键值插入其中 */
}
}
}
}
}
apogeecsj 2003-11-11
  • 打赏
  • 举报
回复
/* btrees.h */
/*
* 平衡多路树的一种重要方案。
* 在 1970 年由 R. Bayer 和 E. McCreight 发明。
*/
#define M 1
/* B 树的阶,即非根节点中键的最小数目。
* 有些人把阶定义为非根节点中子树的最大数目。
*/
typedef int typekey;
typedef struct btnode { /* B-Tree 节点 */
int d; /* 节点中键的数目 */
typekey k[2*M]; /* 键 */
char *v[2*M]; /* 值 */
struct btnode *p[2*M+1]; /* 指向子树的指针 */
} node, *btree;

/* 当 M 等于 1 时也称为 2-3 树
* +----+----+
* | k0 | k1 |
* +-+----+----+---
* | p0 | p1 | p2 |
* +----+----+----+
*/
int btree_disp; /* 查找时找到的键在节点中的位置 */

extern btree search(typekey, btree);
extern btree insert(typekey,btree);
extern btree delete(typekey,btree);
extern int height(btree);
extern int count(btree);
extern btree deltree(btree);
/* end of btrees.h */

/*******************************************************/
pzl 2003-11-09
  • 打赏
  • 举报
回复
up
将帖子提前有问题呀,我隔一天提前,竟然说我太频繁了,只能自己顶一下了
Riemann 2003-11-09
  • 打赏
  • 举报
回复
还是买纸版吧!严蔚敏那本数据结构书也不贵。电子版的你可以去问问LeeMaRS,他好像知道。
pzl 2003-11-06
  • 打赏
  • 举报
回复
是呀,我也听说清华有本书讲的很多,你那里有吗?
bindianxigua 2003-11-06
  • 打赏
  • 举报
回复
在清华那本严的书上有详细介绍啊。
其实掌握概念,很简单的。
zhendeaini190704 2003-11-05
  • 打赏
  • 举报
回复
我有
你可以给我发邮件
jiaoyang1999@163.com
pxwzd123 2003-11-05
  • 打赏
  • 举报
回复
up

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧