首页
社区
课程
招聘
[分享]根据国外的开源B树写了一份C++版本。
发表于: 2013-10-9 19:22 8679

[分享]根据国外的开源B树写了一份C++版本。

2013-10-9 19:22
8679
存在点问题,当order超过2的时候释放的时候要崩溃,哪位大牛能帮忙调试一下这个问题?
数据结构一直没学好,大家别喷,我在努力。。。。。。
用法
void dbScheme::dbTest() {
	int count;
	int order;
	int* values;
	char str[10] = { 0 };
	for (order = 2; order < 60; order++) {
		count = random() % 10;
		values = (int *) leakdbg_malloc(count * sizeof(int));

		for (int i = 0; i < count; i++) {
			values[i] = random() % 1024;
		}

		if (!dbScheme::dbCreate("urls.db", order)) {
			printf("open db fail");
		}
		if (!dbScheme::dbOpen("urls.db")) {
			printf("open db fail");
		}
		for (int i = 0; i < count; i++) {
			for (int j = 0; j < 8; j++) {
				str[j] = 'a' + rand() % ('z' - 'a' + 1);
			}
			str[8] = 0;
			dbScheme::dbPut(str, str);
		}
		dbBytes val;
		if (!dbScheme::dbGet(str, val)) {
			printf("dbGet fail!");
		} else {
			printf("%s\n", val.data());
		}
		dbScheme::dbDel(str);
		dbScheme::print_subtree(dbScheme::dbTree_, dbScheme::dbTree_->root);
		leakdbg_delete(values);
		dbScheme::dbClose();//当order超过2的时候释放的时候要崩溃
	}
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 264
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
//状态宏定义
#define TRUE  1
#define FALSE 0
#define OK    1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW   -2
typedef int Status;


#include "iostream.h"
#include "Define.h"
#define M 3
typedef class BNode						//B-树节点结构体
{
public:
	int Ext;							//节点中包含有效关键字的数目,初始化的时候为0,取值1或2
	int Elem[M-1];						//关键字数组,2个关键字
	BNode *Ptr[M];						//下一级指针,3个指针
	BNode *Parent;						//指向双亲的指针
	int ParentPosition;					//指向该节点的指针在双亲节点下级指针数组中的位置
	BNode();							//构造函数
}BNode,*BTree;


BNode::BNode()
{
	Ext=0;								//初始化元素个数为0
	int i=0;	
	for(i=0;i<M;i++)					//初始化所有指向下级的指针为空
		Ptr[i]=NULL;
	Parent=NULL;						//初始化指向双亲指针为空
	ParentPosition=-1;					//初始化指向该节点的指针在双亲节点下级指针数组中的位置为-1
}


class ElemInfo							//需要加入的节点的信息结构体
{
public:
	int Elem;							//需要加入的关键字
	BNode *EL;							//该关键字对应的左边的指向下级的指针
	BNode *ER;							//该关键字对应的右边的指向下级的指针
	ElemInfo(int x=0){Elem=x;EL=ER=NULL;};//构造函数以x初始化关键字,左右指向下级的指针初始化为空
};

#include "Queue.h"//包含队列头文件



BNode *FindPosition(int Elem,BTree T)		//该函数返回关键字Elem在B-树中应该插入的位置,前提,Elem不在树中
{
	if(!T) return NULL;
	else
	{
		int i=0;
		while(i<T->Ext&&T->Elem[i]<Elem)
			i++;
		BNode *p=FindPosition(Elem,T->Ptr[i]);
		if(p==NULL)   return T;
		else          return p;
	}
}


BNode *InsertElem(ElemInfo EI,BNode * &p)	//该函数完成将节点信息结构体EI插入到p指向的节点当中,用递归完成了分裂和上升
{
	if(!p||p->Ext==0)//插入到空的p中或者p不存在,主要用于处理树的分裂时需要申请新节点和删除时节点的移位
	{
		if(!p)	p=new BNode;		
		p->Elem[0]=EI.Elem;		
		if(EI.ER!=NULL&&EI.EL!=NULL)//插入的同时调整了下级的Parent指针和ParentPosition
		{
			p->Ptr[0]=EI.EL;
			p->Ptr[0]->ParentPosition=0;
			p->Ptr[0]->Parent=p;
			p->Ptr[1]=EI.ER;
			p->Ptr[1]->ParentPosition=1;
			p->Ptr[1]->Parent=p;
		}
		p->Ext++;
		return p;
	}
	else if(p->Ext<M-1)//p中有一个元素
	{
		if(EI.Elem>p->Elem[0])//要插入的关键字大于存在的关键字,插入的同时调整了下级的Parent指针和ParentPosition
		{
			if(EI.ER)
			{
				p->Ptr[2]=EI.ER;
				p->Ptr[2]->ParentPosition=2;
				p->Ptr[2]->Parent=p;
				p->Ptr[1]=EI.EL;
				p->Ptr[1]->ParentPosition=1;
				p->Ptr[1]->Parent=p;
			}
			p->Elem[1]=EI.Elem;
			p->Ext++;
			return p;
		}
		else//要插入的关键字小于存在的关键字,插入的同时调整了下级的Parent指针和ParentPosition
		{
			p->Elem[1]=p->Elem[0];
			if(p->Ptr[1])
			{
				p->Ptr[2]=p->Ptr[1];
				p->Ptr[2]->ParentPosition=2;
				p->Ptr[1]=EI.ER;
				p->Ptr[1]->ParentPosition=1;
				p->Ptr[1]->Parent=p;
				p->Ptr[0]=EI.EL;
				p->Ptr[0]->ParentPosition=0;
				p->Ptr[0]->Parent=p;
			}
			p->Elem[0]=EI.Elem;
			p->Ext++;
			return p;

		}
	}
	//以下是待插入的节点已经存在两个关键字的情况
	else if(EI.Elem>p->Elem[1])//待插入关键字大于已存在的两个关键字
	{
		BNode *newp=new BNode;//分裂

		if(EI.ER)//将待插入的关键字及其信息放入新节点
		{
			newp->Ptr[1]=EI.ER;
			newp->Ptr[1]->ParentPosition=1;
			newp->Ptr[0]=EI.EL;
		}
		
		newp->Elem[0]=EI.Elem;
		newp->Ext++;

		p->Ptr[2]=NULL;
		p->Ext--;

		EI.Elem=p->Elem[1];//将已存在的两个关键字中大的一个封装成下一步的待插入节点
		EI.EL=p;
		EI.ER=newp;
		newp->Parent=InsertElem(EI,p->Parent);//将新的待插入节点插入到现有节点的父亲中,及上升

		if(p->Parent==NULL)
		{
			p->Parent=newp->Parent;
		}
		else if(p->Parent->Ptr[p->ParentPosition]==NULL)
		{
			p->Parent=newp->Parent;
			p->ParentPosition=newp->ParentPosition-1;
		}
		return newp;//调用前的新节点的父亲是这里的新节点
	}
	else if(EI.Elem>p->Elem[0])//待插入的关键字位于已存在的两个关键字中间
	{
		BNode *newp=new BNode;

		if(p->Ptr[2])//将已存在关键字较大的一个放入新生成的节点
		{
			newp->Ptr[1]=p->Ptr[2];
			newp->Ptr[1]->ParentPosition=1;
			newp->Ptr[1]->Parent=newp;
			newp->Ptr[0]=EI.ER;
			newp->Ptr[0]->ParentPosition=0;

		}
		newp->Elem[0]=p->Elem[1];
		newp->Ext++;

		p->Ptr[2]=NULL;
		if(EI.EL)
		{
			p->Ptr[1]=EI.EL;
			p->Ptr[1]->ParentPosition=1;
			p->Ptr[1]->Parent=p;
		}
		p->Ext--;

		EI.EL=p;//更新待插入节点的指针信息
		EI.ER=newp;
		
		newp->Parent=InsertElem(EI,p->Parent);//将待插入节点插入到父亲节点中
		if(p->Parent==NULL)//顶层分裂,产生了新的树根
		{
			p->Parent=newp->Parent;
		}
		else if(p->Parent->Ptr[p->ParentPosition]==NULL)//校正p的ParentPosition信息
		{
			p->Parent=newp->Parent;
			p->ParentPosition=newp->ParentPosition-1;
		}
		return newp;//调用前的新节点的父亲是这里的新节点
	}
	else//待插入的关键字比与存在的两个关键字都要小
	{
		BNode *newp=new BNode;

		if(p->Ptr[2])//将最大的一个放入新的节点,同时调整其子节点的父亲指针和位置标记
		{
			newp->Ptr[1]=p->Ptr[2];
			newp->Ptr[1]->ParentPosition=1;
			newp->Ptr[1]->Parent=newp;
			newp->Ptr[0]=p->Ptr[1];
			newp->Ptr[0]->ParentPosition=0;
			newp->Ptr[0]->Parent=newp;
		}

		newp->Elem[0]=p->Elem[1];
		newp->Ext++;
		newp->Elem[1]=p->Elem[0];//利用新节点后一个关键字的空间暂存中间的关键字

		if(EI.EL)
		{
			p->Ptr[0]=EI.EL;
			p->Ptr[0]->ParentPosition=0;
			p->Ptr[0]->Parent=p;
			p->Ptr[1]=EI.ER;
			p->Ptr[1]->ParentPosition=1;
		}
		
		p->Elem[0]=EI.Elem;//将待插入的节点放入0号位置
		p->Ext--;

		EI.Elem=newp->Elem[1];//将中间节点及其信息封装成新的待插入节点
		EI.EL=p;
		EI.ER=newp;

		newp->Parent=InsertElem(EI,p->Parent);//将型的待插入节点插入其父亲节点
		if(p->Parent==NULL)//顶层分裂,产生了新的树根
		{
			p->Parent=newp->Parent;
		}
		else if(p->Parent->Ptr[p->ParentPosition]==NULL)//校正p的ParentPosition信息
		{
			p->Parent=newp->Parent;
			p->ParentPosition=newp->ParentPosition-1;
		}
		return p;//调用前的新节点的父亲是这里的旧节点
	}
		
}


Status Search(int x,BTree T)		//该函数在B-树中查找关键字x,若存在返回TRUE,不存在返回FALSE
{
	if(!T)    return FALSE;
	int i=0;
	while(i<T->Ext&&T->Elem[i]<x)
		i++;
	if(i<T->Ext&&T->Elem[i]==x)
		return TRUE;
	if(Search(x,T->Ptr[i]))
		return TRUE;
	else return FALSE;
}



Status Insert(int Elem,BTree &T)	//该函数完成将关键字Elem插入到B-树T中
{
	if(Search(Elem,T))				//若关键字已经存在,则插入失败
	{
		cout<<"该关键字已经存在!插入失败!"<<endl;
		return ERROR;
	}
	ElemInfo  temp(Elem);			//构造带插入节点结构体
	BNode *p=FindPosition(Elem,T);	//找到带插入的位置
	if(p)	InsertElem(temp,p);		//若找到,则调用函数插入
	else    InsertElem(temp,T);		//若树为空,插入到根节点
	while(T->Parent)	T=T->Parent;	//重新定位根节点位置
	return OK;
}



BNode *FindDePosition(int x,BTree T)//该函数在B-树中查找关键字x所在的节点,若x不在树中,返回NULL
{
	if(!T)    return NULL;
	int i=0;
	while(i<T->Ext&&T->Elem[i]<x)
		i++;
	if(i<T->Ext&&T->Elem[i]==x)
		return T;
	else 
		return FindDePosition(x,T->Ptr[i]);
}


void DeleteElem(BNode *p,int Elem,BTree &T)//在B-树T中删除p指向的节点中的关键字Elem,通过递归完成对B-树的调整l
{
	if(p->Ext==2)//待删除关键字所在节点中有两个关键字的情况
	{
		if(p->Elem[0]==Elem)
		{
			p->Elem[0]=p->Elem[1];
			if(p->Ptr[2]!=NULL)
			{
				p->Ptr[0]=p->Ptr[1];
				p->Ptr[0]->ParentPosition=0;
				p->Ptr[1]=p->Ptr[2];
				p->Ptr[1]->ParentPosition=1;
			}		
		}
		p->Ptr[2]=NULL;
		p->Ext--;
		return;
	}
	else//p->Ext==1  待删除关键字所在节点只有一个关键字的情况
	{
		BNode *pPare=p->Parent;
		BNode *pLeftInfo=NULL;
		ElemInfo EI;
		if((pLeftInfo=p->Ptr[0])!=NULL||(pLeftInfo=p->Ptr[1])!=NULL)//一下七行将p的剩余信息存到pLfetInfo
			;
		if(pLeftInfo==NULL&&pPare==NULL)//删除根节点并且只剩下根节点的情况
		{
			delete p;
			T=NULL;
			return ;
		}
		if(pPare==NULL)//删除根节点的情况
		{
			delete p;
			T=pLeftInfo;
			T->Parent=NULL;
			T->ParentPosition=-1;
			return;
		}
		if(pPare->Ext==2)
		{
			if(p->ParentPosition==0)
			{
				if(pPare->Ptr[1]->Ext==1)
				{
					if(pPare->Ptr[2]->Ext==1)//case 1
					{
						delete p;
						EI.EL=pLeftInfo;
						EI.ER=pPare->Ptr[1]->Ptr[0];
						EI.Elem=pPare->Elem[0];
						DeleteElem(pPare,pPare->Elem[0],T);
						InsertElem(EI,pPare->Ptr[0]);
						return;
					}
					else//pPare->Ptr[2]->Ext==2   case 3
					{
						EI.EL=pPare->Ptr[1]->Ptr[1];
						EI.Elem=pPare->Elem[1];
						EI.ER=pPare->Ptr[2]->Ptr[0];
						InsertElem(EI,pPare->Ptr[1]);
						pPare->Elem[1]=pPare->Ptr[2]->Elem[0];
						DeleteElem(pPare->Ptr[2],pPare->Ptr[2]->Elem[0],T);
						DeleteElem(p,p->Elem[0],T);
						return;
					}
				}
				else//pPare->Ptr[1]->Ext==2  case 2
				{
					p->Ext--;
					EI.EL=pLeftInfo;
					EI.ER=pPare->Ptr[1]->Ptr[0];
					EI.Elem=pPare->Elem[0];
					InsertElem(EI,p);
					pPare->Elem[0]=pPare->Ptr[1]->Elem[0];
					DeleteElem(pPare->Ptr[1],pPare->Ptr[1]->Elem[0],T);
					return ;
				}
			}
			else if(p->ParentPosition==1)
			{
				if(pPare->Ptr[2]->Ext==1)
				{
					if(pPare->Ptr[0]->Ext==1)//case 6
					{
						delete p;
						EI.EL=pLeftInfo;
						EI.ER=pPare->Ptr[2]->Ptr[0];
						EI.Elem=pPare->Elem[1];
						pPare->Ptr[1]=pPare->Ptr[2];
						pPare->Ptr[1]->ParentPosition=1;
						InsertElem(EI,pPare->Ptr[1]);
						DeleteElem(pPare,pPare->Elem[1],T);
						return ;
					}
					else//pPare->Ptr[0]->Ext==2  case 5
					{
						p->Ext--;
						EI.EL=pPare->Ptr[0]->Ptr[2];
						EI.ER=pLeftInfo;
						EI.Elem=pPare->Elem[0];
						InsertElem(EI,p);
						pPare->Elem[0]=pPare->Ptr[0]->Elem[1];
						DeleteElem(pPare->Ptr[0],pPare->Ptr[0]->Elem[1],T);
						return ;
					}
				}
				else//pPare->Ptr[2]->Ext==2  case 4
				{
					p->Ext--;
					EI.EL=pLeftInfo;
					EI.ER=pPare->Ptr[2]->Ptr[0];
					EI.Elem=pPare->Elem[1];
					InsertElem(EI,p);
					pPare->Elem[1]=pPare->Ptr[2]->Elem[0];
					DeleteElem(pPare->Ptr[2],pPare->Ptr[2]->Elem[0],T);
					return ;
				}
			}
			else//p->ParentPosition==2
			{
				if(pPare->Ptr[1]->Ext==2)//case 7
				{
					p->Ext--;
					EI.EL=pPare->Ptr[1]->Ptr[2];
					EI.ER=pLeftInfo;
					EI.Elem=pPare->Elem[1];
					InsertElem(EI,p);
					pPare->Elem[1]=pPare->Ptr[1]->Elem[1];
					DeleteElem(pPare->Ptr[1],pPare->Ptr[1]->Elem[1],T);
					return ;
				}
				else//pPare->Ptr[1]->Ext==1
				{
					if(pPare->Ptr[0]->Ext==1)//case  9
					{
						delete p;
						EI.EL=pPare->Ptr[1]->Ptr[1];
						EI.ER=pLeftInfo;
						EI.Elem=pPare->Elem[1];
						InsertElem(EI,pPare->Ptr[1]);
						DeleteElem(pPare,pPare->Elem[1],T);
						return;
					}
					else//pPare->Ptr[0]->Ext==2   case 8
					{
						EI.EL=pPare->Ptr[0]->Ptr[2];
						EI.Elem=pPare->Elem[0];
						EI.ER=pPare->Ptr[1]->Ptr[0];
						InsertElem(EI,pPare->Ptr[1]);
						pPare->Elem[0]=pPare->Ptr[0]->Elem[1];
						DeleteElem(pPare->Ptr[0],pPare->Ptr[0]->Elem[1],T);
						DeleteElem(p,p->Elem[0],T);
						return;
					}
				}
			}
		}
		else//pPare->Ext==1
		{
			if(p->ParentPosition==0)
			{
				if(pPare->Ptr[1]->Ext==1)//case 11
				{
					delete p;
					EI.EL=pLeftInfo;
					EI.ER=pPare->Ptr[1]->Ptr[0];
					EI.Elem=pPare->Elem[0];
					InsertElem(EI,pPare->Ptr[1]);
					pPare->Ptr[0]=NULL;
					DeleteElem(pPare,pPare->Elem[0],T);
					return ;
				}
				else//pPare->Ptr[1]->Ext==2  case 10
				{
					p->Ext--;
					EI.EL=pLeftInfo;
					EI.ER=pPare->Ptr[1]->Ptr[0];
					EI.Elem=pPare->Elem[0];
					InsertElem(EI,p);
					pPare->Elem[0]=pPare->Ptr[1]->Elem[0];
					DeleteElem(pPare->Ptr[1],pPare->Ptr[1]->Elem[0],T);
					return ;
				}
			}
			else//p->ParentPosition==1
			{
				if(pPare->Ptr[0]->Ext==1)//case 13
				{
					delete p;
					EI.EL=pPare->Ptr[0]->Ptr[1];
					EI.ER=pLeftInfo;
					EI.Elem=pPare->Elem[0];
					InsertElem(EI,pPare->Ptr[0]);
					pPare->Ptr[1]=NULL;
					DeleteElem(pPare,pPare->Elem[0],T);
					return ;
				}
				else//pPare->Ptr[0]==2   case  12
				{
					p->Ext--;
					EI.EL=pPare->Ptr[0]->Ptr[2];
					EI.ER=pLeftInfo;
					EI.Elem=pPare->Elem[0];
					InsertElem(EI,p);
					pPare->Elem[0]=pPare->Ptr[0]->Elem[1];
					DeleteElem(pPare->Ptr[0],pPare->Ptr[0]->Elem[1],T);
					return ;
				}
			}
		}
	}
}
Status Delete(int Elem,BTree &T)//该函数完成在B-树中删除关键字Elem
{
	BNode *p=FindDePosition(Elem,T);//指向待删除的关键字所在节点的指针
	if(p==NULL)
	{
		cout<<"关键字:"<<Elem<<"不在树中,无法进行删除操作"<<endl;
		return FALSE;
	}
	int ElemPos=(p->Elem[0]==Elem)?0:1;//待删除关键字在其所在节点的位置
	if(p->Ptr[0]!=NULL)    //若待删除的关键字不在叶子节点中,找到其右边的最左边替换,转换成删除叶子节点
	{
		BNode *q=p->Ptr[ElemPos+1];
		while(q->Ptr[0]!=NULL)
			q=q->Ptr[0];
		Elem=p->Elem[ElemPos]=q->Elem[0];
		p=q;
		ElemPos=0;		
	}
	//至此已经将问题转化成删除值为Elem的关键字,该关键字在p所指向的叶子节点中
	DeleteElem(p,Elem,T);
	return OK;
}


void Print(BTree T)					//以层次遍历输出树
{	
	if(!T)
	{
		cout<<"空树!"<<endl;
		return;
	}
	LinkQueue a,b;					//用到2个队列以完成分层输出
	InitQueue(a);				
	InitQueue(b);
	BNode *temp;
	int n;
	EnQueue(a,T);
	while(!QueueEmpty(a)||!QueueEmpty(b))//两个队列都为空时,输出结束
	{
		if(!QueueEmpty(a))
		{
			while(!QueueEmpty(a))
			{
				DeQueue(a,temp);
				for(n=0;n<temp->Ext;n++)
				{
					cout<<temp->Elem[n]<<"+";
					if(temp->Ptr[n]) EnQueue(b,temp->Ptr[n]);
				}
				if(temp->Ptr[n]) EnQueue(b,temp->Ptr[n]);
				cout<<"\b   ";
			}
			cout<<endl;
		}
		else
		{
			while(!QueueEmpty(b))
			{
				DeQueue(b,temp);
				for(n=0;n<temp->Ext;n++)
				{
					cout<<temp->Elem[n]<<"+";
					if(temp->Ptr[n]) EnQueue(a,temp->Ptr[n]);
				}
				if(temp->Ptr[n]) EnQueue(a,temp->Ptr[n]);
				cout<<"\b   ";
			}
			cout<<endl;
		}
	}
}


void PrintDetails(BTree T)//用层次遍历输出每一个节点的详细信息,调试用函数
{
	if(!T)
	{
		cout<<"树为空树!"<<endl;
		return;
	}
	LinkQueue a;					//以一个队列层次遍历
	InitQueue(a);
	BNode *temp;
	int n,m=1;
	EnQueue(a,T);
	while(!QueueEmpty(a))
	{
		DeQueue(a,temp);
		cout<<"节点序号:"<<m<<endl;
		cout<<"所含关键字个数:"<<temp->Ext<<endl;
		cout<<"所含关键字为:";
		for(n=0;n<temp->Ext;n++)
		{
			cout<<temp->Elem[n]<<"  ";
		}
		cout<<endl;
		cout<<endl;
		for(n=0;n<3;n++)
		{
			if(temp->Ptr[n])
			{
				EnQueue(a,temp->Ptr[n]);
				cout<<"孩子"<<n<<"的第一个关键字:"<<temp->Ptr[n]->Elem[0]<<endl;
			}
			else
			{
				cout<<"孩子"<<n<<"不存在"<<endl;
			}
		}
		cout<<endl;
		if(temp->Parent)
		{
			cout<<"父亲的第一个关键字:"<<temp->Ptr[n]->Elem[0]<<endl;
			cout<<"该节点在父亲中的位置"<<temp->ParentPosition<<endl;
		}
		else
		{
			cout<<"父亲不存在"<<endl;
		}
		system("pause");
		system("cls");
		m++;
	}
	cout<<"输出结束!"<<endl;
	system("pause");
}

void Destroy(BTree &T)//销毁B-树T,算法思想就是不算的删除根关键字直到树空
{
	while(T)
	{
		Delete(T->Elem[0],T);
	}
}


#include "iostream.h"
typedef  BTree QElemType;
typedef struct QNode					//队列的节点类型
{
	QElemType data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef  struct							//队列类型声明
{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

Status InitQueue(LinkQueue &Q)			//初始化队列,申请专用的对头节点
{
	Q.front=Q.rear=new QNode;
	if(!Q.front)   return OVERFLOW;
	Q.front->next=NULL;
	return OK;
}

Status ClearQueue(LinkQueue &Q)			//清空队列,只剩下专用的头节点
{
	if(Q.front==Q.rear) return OK;
	QNode *p=Q.front->next;
	while(p)
	{
		Q.front->next=p->next;
		delete p;
		p=Q.front->next;
	}
	Q.rear=Q.front;
	return OK;
}

Status DestroyQueue(LinkQueue &Q)		//销毁队列,在清空的基础上删除专用头结点
{
	ClearQueue(Q);
	delete Q.front;
	Q.front=Q.rear=NULL;
	return OK;
}

Status QueueEmpty(LinkQueue Q)			//队列判空,如果是空队列返回TRUE,否则返回FALSE
{
	if(Q.rear==Q.front) return TRUE;
		else return FALSE;
}
 
int QueueLength(LinkQueue Q)			//求队列长度
{
	int cout=0;
	QNode *p=Q.front->next;
	while(p)
	{
		cout++;
		p=p->next;
	}
	return cout;
}

Status QueueTraverse(LinkQueue &Q)		//遍历队列,输出队列中的元素
{
	if(Q.front==Q.rear)
	{
		cout<<"空队"<<endl;
		return OK;
	}
	QNode *p=Q.front->next;
	while(p)
	{ 
		cout<<p->data<<endl;
		p=p->next;
	}
	return OK;
}

Status GetHead(LinkQueue Q,QElemType &e)		//取头结点,将其数据放到e中
{
	if(QueueEmpty(Q))
		return ERROR;
	else
	{
		e=Q.front->next->data;
		return OK;
	}
}
 
Status EnQueue(LinkQueue &Q,QElemType &e)		//将e入队
{
	Q.rear->next=new QNode;
	if(!Q.rear->next)
		return OVERFLOW;
	Q.rear=Q.rear->next;
	Q.rear->data=e;
	Q.rear->next=NULL;
	return OK;
}


Status DeQueue(LinkQueue &Q,QElemType &e)		//出队,将出对的元素放入e中
{
	if(!GetHead(Q,e))
		return ERROR;
	if(Q.rear==Q.front->next)
		Q.rear=Q.front;
	QNode *p=Q.front->next;
	Q.front->next=p->next;
	delete p;
	return OK;
}
  #include "Testmode.h"
  void Frist()						//开始界面
  {
  	cout <<"************************************************" <<endl;
  	cout <<"课程设计:B-Trees 的实现及分析" <<endl;
  	cout <<"班级:09计算机1班" <<endl;
  	cout <<"学号:0900303128" <<endl;
  	cout <<"姓名:胡远璇" <<endl;
  	cout <<"************************************************" <<endl;
  	cout <<endl;
  	cout <<endl;
  	cout <<"介绍:" <<endl;
  	cout <<endl;
  	cout <<"该程序是M=3的的B-树" <<endl;
  	cout <<endl;
  	cout <<"该程序包含:" <<endl;
  	cout <<"1.实现在B-树上的查找" <<endl;
  	cout <<"2.实现B-树的ADT,包括其上的基本操作:结点的加入和删除" <<endl;
  	cout <<endl;
  	cout <<endl;
  	system("pause");
  
  }
  
  void systemmenu()					//顶级的系统菜单
  {
  	char choose=0;
  	while(1)
  	{
  		system("cls");
  		cout <<"测试模式选择" <<endl;
  		cout <<"A.指定关键字插入删除测试" <<endl;
  		cout <<"E.退出系统" <<endl;
  		choose=getch();
  		if(toupper(choose)=='A')	
  		{
  			BTree T=NULL;
  			InputIDTest(T);
  		}
  		if(toupper(choose)=='E')	break;
  	}
  }
  
  void End()        //结束界面
  {
  	system("cls");
  	cout <<"************************************************" <<endl;
  	cout <<"程序结束" <<endl;
  	cout <<"2011-1-15" <<endl;
  	cout <<"************************************************" <<endl;
  	system("pause");
  
  }
  
  void main()
  {
  	Frist();
  	systemmenu();
  	End();
  
  }

2013-10-9 22:11
0
雪    币: 40
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
试试google的 https://code.google.com/p/cpp-btree/
2013-10-9 22:22
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
4
人家写的我不要,我要自己写。
2013-10-9 22:24
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
5
感谢老兄的代码,我研究一下.
2013-10-9 22:25
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学数据结构的话。 还是应该先看书,或者先看图。 算法导论和“数据结构” 这本书里面都有B树的图。 我觉得还算是深入浅出。 红黑树什么的也讲的很好。
2013-10-10 09:25
0
游客
登录 | 注册 方可回帖
返回
//