严蔚敏数据结构B树与B+树

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <math.h>
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define OVERFLOW -2
#define LH 1
#define RH -1
#define EH 0
#define GRADE 4
typedef int Status;
typedef int KeyType;
typedef struct
{
	KeyType key;
}ElemType;
typedef struct
{
	ElemType* elem;
	int length;
}SSTable;
typedef ElemType TElemType;
typedef struct BiTNode
{
	TElemType data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
typedef struct BSTNode
{
	TElemType data;
	int bf;
	struct BSTNode* lchild, * rchild;
}BSTNode, * BSTree;
typedef struct BTNode
{
	int keynum;
	struct BTNode* parent;
	KeyType key[GRADE + 1];
	struct BTNode* ptr[GRADE + 2];
	ElemType* recptr[GRADE + 1];
}BTNode, * BTree;
typedef struct
{
	BTNode* ptr;
	int i;
	int tag;
}Result;


//查找表元素输入,关键字赋值以及比较
void InputTableElem(ElemType* e)
{
	printf("请输入关键字信息\n");
	scanf("%d", &(e->key));
}
void KeyWordAssign(KeyType* destination, KeyType source)
{
	(*destination) = source;
}
void KeyWordPrint(KeyType key)
{
	printf("%d\n", key);
}
void TableElemAssign(ElemType* destination, ElemType source)
{
	(*destination).key = source.key;
}
void TableElemPrint(ElemType e)
{
	printf("%d\n", e.key);
}
Status EQ(KeyType key1, KeyType key2)
{
	if (key1 == key2)
		return TRUE;
	else
		return FALSE;
}
Status LT(KeyType key1, KeyType key2)
{
	if (key1 < key2)
		return TRUE;
	else
		return FALSE;
}
Status LE(KeyType key1, KeyType key2)
{
	if (key1 <= key2)
		return TRUE;
	else
		return FALSE;
}
Status MT(KeyType key1, KeyType key2)
{
	if (key1 > key2)
		return TRUE;
	else
		return FALSE;
}
Status ME(KeyType key1, KeyType key2)
{
	if (key1 >= key2)
		return TRUE;
	else
		return FALSE;
}


//静态查找表
Status CreatSSTable(SSTable* T, int n)
{
	T->length = n;
	T->elem = (ElemType*)malloc(sizeof(ElemType) * (n + 1));
	if (!T->elem) exit(OVERFLOW);
	for (int i = 1; i <= T->length; i++)
	{
		printf("请输入第%d个表项信息:\n", i);
		InputTableElem(&(T->elem[i]));
	}
	return OK;
}
int Search_Seq(SSTable ST, KeyType key)                   //Sequence Search
{
	KeyWordAssign(&(ST.elem[0].key), key);
	int i = ST.length;
	while (!EQ(ST.elem[i].key, key))
		i--;
	return i;
}
int Search_Bin(SSTable ST, KeyType key)                    //Binary Search
{
	int low = 1, high = ST.length;
	int mid = (low + high) / 2;
	while (low <= high)
	{
		if (EQ(ST.elem[mid].key, key))
			return mid;
		if (MT(ST.elem[mid].key, key))
			high = mid - 1;
		else
			low = mid + 1;
	}
	return 0;
}
void SecondOptimal(BiTree* T, SSTable S, int* sw, int low, int high)
{
	int i = low;
	int w = sw[high] + sw[low - 1];
	int min = abs(sw[high] - sw[low]);
	for (int j = low + 1; j <= high; j++)
	{
		if (abs(w - sw[j - 1] - sw[j]) < min)
		{
			i = j;
			min = abs(w - sw[i] - sw[i - 1]);
		}
	}
	(*T) = (BiTree)malloc(sizeof(BiTNode));
	if (!(*T)) exit(OVERFLOW);
	KeyWordAssign(&((*T)->data.key), S.elem[i].key);
	if (i == low)
		(*T)->lchild = NULL;
	else
		SecondOptimal(&((*T)->lchild), S, sw, low, i - 1);
	if (i == high)
		(*T)->rchild = NULL;
	else
		SecondOptimal(&((*T)->rchild), S, sw, i + 1, high);
}


//队列函数
typedef BTNode* QElemType;
typedef struct QNode
{
	QElemType data;
	struct QNode* next;
}QNode, * QueuePtr;
typedef struct
{
	QueuePtr head, tail;
}LinkQueue;
Status InitQueue(LinkQueue* Q)
{
	Q->head = (QueuePtr)malloc(sizeof(QNode));
	if (!Q->head) exit(OVERFLOW);
	Q->tail = Q->head;
	Q->head->next = NULL;
	return OK;
}
Status EnQueue(LinkQueue* Q, QElemType e)
{
	QNode* p;
	p = (QNode*)malloc(sizeof(QNode));
	if (!p) exit(OVERFLOW);
	p->data = e;
	Q->tail->next = p;
	Q->tail = p;
	Q->tail->next = NULL;
	return OK;
}
Status DeQueue(LinkQueue* Q, QElemType* e)
{
	if (Q->head == Q->tail)
		return ERROR;
	QNode* p = Q->head->next;
	(*e) = p->data;
	Q->head->next = p->next;
	if (p == Q->tail)
		Q->tail = Q->head;
	free(p);
	return OK;
}
Status QueueEmpty(LinkQueue Q)
{
	if (Q.head == Q.tail)
		return TRUE;
	else
		return FALSE;
}

//B-树与B+树
void PrintBTree(BTree T)
{
	if (!T)
		printf("B-树为空\n");
	else
	{
		printf("B树层序输出为:\n");
		LinkQueue Q;
		InitQueue(&Q);
		EnQueue(&Q, T);
		QElemType p;
		while (!QueueEmpty(Q))
		{
			DeQueue(&Q, &p);
			int i = 0;
			while (i < p->keynum)
			{
				//KeyWordPrint(p->key[i]);
				TableElemPrint(*(p->recptr[i]));
				if (p->ptr[i])
					EnQueue(&Q, p->ptr[i]);
				i++;
			}
			if (p->ptr[i])
				EnQueue(&Q, p->ptr[i]);
		}
	}
}
int Search(BTree T, KeyType key)                                       //找B-树的一个节点中找记录,若找到,为找到记录的位置,未找到则为插入位置
{                                                                      //若树不存在,则位置为0
	int i = 0;
	while (T && i < T->keynum && LT(T->key[i], key))
		i++;
	return i;
}
Status SearchBTree(BTree T, KeyType key, Result* res)
{
	BTNode* p = T, * q = NULL;
	int found = FALSE;
	int i = 0;
	while (p && (found == FALSE))
	{
		i = Search(p, key);
		if (i < p->keynum && EQ(p->key[i], key))
			found = TRUE;
		else
		{
			q = p;
			p = p->ptr[i];
		}
	}
	if (found)
	{
		res->tag = TRUE;
		res->i = i;
		res->ptr = p;
	}
	else
	{
		res->tag = FALSE;
		res->i = i;
		res->ptr = q;
	}
	return OK;
}
Status CreatBTNode(BTree* T, ElemType e)
{
	(*T) = (BTree)malloc(sizeof(BTNode));
	if (!(*T)) exit(OVERFLOW);
	(*T)->keynum = 1;
	KeyWordAssign(&((*T)->key[0]), e.key);
	(*T)->recptr[0] = (ElemType*)malloc(sizeof(ElemType));
	if (!(*T)->recptr[0]) exit(OVERFLOW);
	TableElemAssign((*T)->recptr[0], e);
	return OK;
}
int Split(BTree T1, BTree T2)
{
	int split = ceil(GRADE / 2);
	T1->keynum = split - 1;
	T2->keynum = GRADE - split;
	split--;
	for (int i = split + 1; i < GRADE; i++)
	{
		KeyWordAssign(&(T2->key[i - split - 1]), T1->key[i]);
		T2->ptr[i - split - 1] = T1->ptr[i];
		T2->recptr[i - split - 1] = T1->recptr[i];
	}
	T2->ptr[GRADE - split - 1] = T1->ptr[GRADE];
	return split;
}
Status InsertBTree(BTree* ROOT, BTree* T, int pos, ElemType e, BTree T1, BTree T2)
{
	if (!(*T))
	{
		CreatBTNode(ROOT, e);
		(*ROOT)->parent = NULL;
		(*ROOT)->ptr[pos] = T1;
		(*ROOT)->ptr[pos + 1] = T2;
		(*T) = (*ROOT);
	}
	else
	{
		if ((*T)->keynum < GRADE)
		{
			int i = (*T)->keynum - 1;
			while (i >= pos)
			{
				(*T)->ptr[i + 2] = (*T)->ptr[i + 1];
				KeyWordAssign(&((*T)->key[i + 1]), (*T)->key[i]);
				(*T)->recptr[i + 1] = (*T)->recptr[i];
				i--;
			}
			KeyWordAssign(&((*T)->key[pos]), e.key);
			(*T)->recptr[pos] = (ElemType*)malloc(sizeof(ElemType));
			if (!(*T)->recptr[pos]) exit(OVERFLOW);
			TableElemAssign((*T)->recptr[pos], e);
			(*T)->ptr[pos] = T1;
			(*T)->ptr[pos + 1] = T2;
			(*T)->keynum++;
		}
		if ((*T)->keynum == GRADE)
		{
			BTNode* new;
			new = (BTNode*)malloc(sizeof(BTNode));
			if (!new) exit(OVERFLOW);
			int splitpos = Split((*T), new);
			int i = Search((*T)->parent, (*T)->key[splitpos]);
			InsertBTree(ROOT, &((*T)->parent), i, *((*T)->recptr[splitpos]), (*T), new);
			new->parent = (*T)->parent;
			(*T) = (*T)->parent;
		}
	}
	return OK;
}
Status Delete_BT(BTree* ROOT, BTree* T, int pos)
{
	int min = ceil(GRADE / 2) - 1;
	for (int i = pos; i <= (*T)->keynum - 2; i++)
	{
		KeyWordAssign(&((*T)->key[i]), (*T)->key[i + 1]);
		(*T)->recptr[i] = (*T)->recptr[i + 1];
	}
	(*T)->keynum--;
	if ((*T) == (*ROOT))
	{
		if ((*T)->keynum == 0)
			(*ROOT) = (*T)->ptr[0];
	}
	else
	{
		if ((*T)->keynum < min)
		{
			BTNode* parent = (*T)->parent;
			BTNode* lsibling = NULL, * rsibling = NULL, * helpsibling = NULL;
			int childpos = Search(parent, (*T)->key[pos]);
			if (childpos - 1 > 0)
				lsibling = parent->ptr[childpos - 1];
			if (childpos + 1 <= parent->keynum)
				rsibling = parent->ptr[childpos + 1];
			int tag = 0;
			if (lsibling)
			{
				tag = 1;
				helpsibling = lsibling;
			}
			if (rsibling)
			{
				tag = 2;
				helpsibling = rsibling;
			}
			if (lsibling && lsibling->keynum > min)
			{
				tag = 3;
				helpsibling = lsibling;
			}
			if (rsibling && rsibling->keynum > min)
			{
				tag = 4;
				helpsibling = rsibling;
			}
			int last;
			switch (tag)
			{
			case 1:
				last = helpsibling->keynum;
				KeyWordAssign(&(helpsibling->key[last]), parent->key[childpos - 1]);
				helpsibling->recptr[last] = (ElemType*)malloc(sizeof(ElemType));
				if (!helpsibling->recptr[last]) exit(OVERFLOW);
				helpsibling->recptr[last] = parent->recptr[childpos - 1];
				helpsibling->keynum++;
				last++;
				for (int i = 0; i < (*T)->keynum; i++)
				{
					KeyWordAssign(&(helpsibling->key[last + i]), (*T)->key[i]);
					helpsibling->recptr[last + i] = (ElemType*)malloc(sizeof(ElemType));
					if (!helpsibling->recptr[last + i]) exit(OVERFLOW);
					helpsibling->recptr[last + i] = (*T)->recptr[i];
					helpsibling->keynum++;
					helpsibling->ptr[last + i] = (*T)->ptr[i];
				}
				helpsibling->ptr[helpsibling->keynum] = (*T)->ptr[(*T)->keynum];
				for (int i = parent->keynum - 1; i >= childpos; i--)
					parent->ptr[i] = parent->ptr[i + 1];
				Delete_BT(ROOT, &parent, childpos - 1);
				break;
			case 2:
				last = (*T)->keynum;
				KeyWordAssign(&((*T)->key[last]), parent->key[childpos]);
				(*T)->recptr[last] = (ElemType*)malloc(sizeof(ElemType));
				if (!(*T)->recptr[last]) exit(OVERFLOW);
				(*T)->recptr[last] = parent->recptr[childpos];
				(*T)->keynum++;
				last++;
				for (int i = 0; i < helpsibling->keynum; i++)
				{
					KeyWordAssign(&((*T)->key[last + i]), helpsibling->key[i]);
					(*T)->recptr[last + i] = (ElemType*)malloc(sizeof(ElemType));
					if (!(*T)->recptr[last + i]) exit(OVERFLOW);
					(*T)->recptr[last + i] = helpsibling->recptr[i];
					(*T)->keynum++;
					(*T)->ptr[last + i] = helpsibling->ptr[i];
				}
				(*T)->ptr[(*T)->keynum] = helpsibling->ptr[helpsibling->keynum];
				for (int i = parent->keynum - 1; i >= childpos + 1; i--)
					parent->ptr[i] = parent->ptr[i + 1];
				Delete_BT(ROOT, &parent, childpos);
				break;
			case 3:
				(*T)->ptr[(*T)->keynum + 1] = (*T)->ptr[(*T)->keynum];
				for (int i = (*T)->keynum - 1; i > 0; i--)
				{
					KeyWordAssign(&((*T)->key[i + 1]), (*T)->key[i]);
					(*T)->recptr[i + 1] = (*T)->recptr[i];
					(*T)->ptr[i + 1] = (*T)->ptr[i];
				}
				KeyWordAssign(&((*T)->key[0]), parent->key[childpos - 1]);
				(*T)->recptr[0] = parent->recptr[childpos - 1];
				(*T)->keynum++;
				last = helpsibling->keynum;
				KeyWordAssign(&(parent->key[childpos - 1]), helpsibling->key[last - 1]);
				parent->recptr[childpos - 1] = helpsibling->recptr[last - 1];
				(*T)->ptr[0] = helpsibling->ptr[last];
				Delete_BT(ROOT, &helpsibling, last - 1);
				break;
			case 4:
				last = (*T)->keynum;
				KeyWordAssign(&((*T)->key[last]), parent->key[childpos]);
				(*T)->recptr[last] = parent->recptr[childpos];
				(*T)->keynum++;
				KeyWordAssign(&(parent->key[childpos]), helpsibling->key[0]);
				parent->recptr[childpos] = helpsibling->recptr[0];
				(*T)->ptr[(*T)->keynum] = helpsibling->ptr[0];
				for (int i = 0; i < helpsibling->keynum; i++)
					helpsibling->ptr[i] = helpsibling->ptr[i + 1];
				Delete_BT(ROOT, &helpsibling, 0);
				break;
			default:
				return ERROR;
			}
		}
	}
}
Status DeleteBTree(BTree* ROOT, BTree* T, int pos)
{
	if ((*T)->ptr[pos] != NULL)
	{
		Result res;
		SearchBTree((*T)->ptr[pos], (*T)->key[pos], &res);
		KeyWordAssign(&((*T)->key[pos]), res.ptr->key[res.i - 1]);
		(*T)->recptr[pos] = res.ptr->recptr[res.i - 1];
		Delete_BT(ROOT, &(res.ptr), res.i - 1);
	}
	else
		Delete_BT(ROOT, T, pos);
	return OK;
}

主函数:

//B-树主函数
int main()
{
	BTree T = NULL, ROOT = NULL;
	Result res;
	int count = 10;
	ElemType e;
	while (count)
	{
		InputTableElem(&e);
		SearchBTree(ROOT, e.key, &res);
		T = res.ptr;
		InsertBTree(&ROOT, &T, res.i, e, NULL, NULL);
		count--;
	}
	PrintBTree(ROOT);
	count = 10;
	printf("--------------------------------\n\n");
	while (count && ROOT)
	{
		printf("需要输入关键字以删除节点\n");
		InputTableElem(&e);
		SearchBTree(ROOT, e.key, &res);
		T = res.ptr;
		DeleteBTree(&ROOT, &T, res.i);
		PrintBTree(ROOT);
		printf("--------------------------------\n\n");
		count--;
	}
	return 0;
}

输入:(P245所示B树构造,然后将B树节点一一删去)

45
24
53
90
3
37
50
61
70
100

输出:

 删除45:

 以此类推以验证程序正确性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值