您的位置:首页 > 博客中心 > 编程语言 >

数据结构 - 二叉排序树的实现

时间:2022-03-24 19:33


二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树。 

它或者是一棵空树;或者是具有下列性质的二叉树: 

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; 

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; 

(3)左、右子树也分别为二叉排序树;



上机代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath> 
using namespace std;

#define KeyType int 
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)< (b))
#define LQ(a,b) ((a)<=(b))
#define FALSE 0
#define TRUE 1 
#define OK 1
//#define OVERFLOW 0
#define ERROR 0
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

typedef struct  
{
	KeyType key;                                                //关键字域
} ElemType;                                                                                   

typedef struct BiTNode               //定义二叉树二叉链表
{
	ElemType  data;
	struct BiTNode *lchild, *rchild;
}BiTNode,*BiTree,*SElemType;

typedef struct
{
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;

int DestroyBiTree(BiTree &T) //销毁树
{
	if(T!=NULL)
	free(T);
	return 0;
}

int ClearBiTree(BiTree &T) //清空树
{
	if(T!=NULL)
	{
		T->lchild=NULL;
		T->rchild=NULL;
		T=NULL;
	}
	return 0;
}

int SearchBST(BiTree T,KeyType key,BiTree f,BiTree &p)    //查找关键字,指针p返回
{
	if(!T)
	{
		p=f;
		return FALSE;
	}
	else if EQ(key,T->data.key) 
	{
		p=T;
		return TRUE;
	}
	else if LT(key,T->data.key)
		return SearchBST(T->lchild,key,T,p);
	else 
		return SearchBST(T->rchild,key,T,p);
}

int InsertBST(BiTree &T,ElemType e)   //插入节点元素
{
	BiTree s,p;
	if(!SearchBST(T,e.key,NULL,p))
	{
		s=(BiTree)malloc(sizeof(BiTNode));
		s->data=e;
		s->lchild=s->rchild=NULL;
		if(!p)
			T=s;
		else if LT(e.key,p->data.key)
			p->lchild=s;
		else 
			p->rchild=s;
		return TRUE;
	}
	else return FALSE;
}

int ShowBST(BiTree T,int nlayer)      //显示树形二叉排序树
{
	int i;
	if(T==NULL)  
		return FALSE;
	ShowBST(T->rchild,nlayer+1);
	for(i=0;i<nlayer;i++)
		printf("    ");
	printf("%d\n",T->data);
	ShowBST(T->lchild,nlayer+1);
	return OK;
}

int Visit(ElemType e)  //Visit函数
{
	printf("%d ",e.key);
	return OK;
}

int InitStack(SqStack &S)   //构造空栈
{
	S.base=(SElemType*)malloc(STACK_INIT_SIZE *sizeof(SElemType));
	if(!S.base) exit(OVERFLOW);
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
	return OK;
}//InitStack

int Push(SqStack &S, SElemType e)  //插入元素e为新栈顶
{
	if(S.top-S.base>=S.stacksize)
	{
		S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!S.base) exit(OVERFLOW);
		S.top=S.base+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top++=e;
	return OK;
}//Push

int Pop(SqStack &S,SElemType &e)  //删除栈顶,应用e返回其值
{
	if(S.top==S.base)  return ERROR;
	e=*--S.top;
	return OK;
}//Pop

int StackEmpty(SqStack S)          //判断是否为空栈
{
	if(S.base==S.top) return TRUE;
	return FALSE;
}

int PreOrderTraverse(BiTree T,int(*Visit)(ElemType e))  //先序遍历,运用栈
{
	SqStack S;
	BiTree p;
	InitStack(S);
	p=T;
	while(p|| !StackEmpty(S))
	{
		if(p)
		{
			Push(S,p);
			if(!Visit(p->data)) return ERROR;   
			p=p->lchild;
		}
		else
		{
			Pop(S, p);
			p=p->rchild;
		}
	}
	return OK;
}

int InOrderTraverse(BiTree T, int(*Visit)(ElemType e))  //中序遍历,运用栈
{
	SqStack S;
	BiTree p;
	InitStack(S);
	p=T;
	while(p|| !StackEmpty(S))
	{
		if(p)
		{
			Push(S,p);
			p=p->lchild;
		}
		else
		{
			Pop(S,p);
			if(!Visit(p->data)) return ERROR;
			p=p->rchild;
		}
	
	}
	return OK;
}

int PostOrderTraverse(BiTree T,int(*Visit)(ElemType e)) //后序遍历,运用栈
{
	SqStack S,SS;
	BiTree p;
	InitStack(S);
	InitStack(SS);
	p=T;
	while(p|| !StackEmpty(S))
	{
		if(p)
		{
			Push(S,p);
			Push(SS,p);
			p=p->rchild;
		}
		else
		{
			if(!StackEmpty(S))
			{
				Pop(S, p);
				p=p->lchild;
			}
		}
	}
    while(!StackEmpty(SS))
    {
        Pop(SS, p);
		if(!Visit(p->data)) return ERROR;     
    }
	return OK;
}

int Delete(BiTree &p) // 三种删除节点的操作实现
{
	BiTree q,s;
	if(!p->rchild)    //右子树为空
	{
		q=p;
		p=p->lchild;
		free(q);
	}
	else if(!p->lchild)    //左子树为空
	{
		q=p;
		p=p->rchild;
		free(q);
	}
	else
	{
		q=p;
		s=p->lchild;
		while(s->rchild)
		{
			q=s;
			s=s->rchild;
		}
		p->data=s->data;
		if(q!=p)
			q->rchild=s->lchild;
		else
			q->lchild=s->lchild;
		free(s);
	}
	return TRUE;
}

int DeleteBST(BiTree &T,KeyType key) //实现二叉排序树的删除操作
{
	if(!T)
		return FALSE;
	else
	{
		if (EQ(key,T->data.key))       //T->data.key等于key
			return Delete(T);
		else if (LT(key,T->data.key))   //T->data.key是否小于key
			return DeleteBST(T->lchild,key);
		else 
			return DeleteBST(T->rchild,key);
	}
	return 0;
}

int main()
{
	int i,nlayer;
	ElemType k,d;
    BiTree  BT,p;
	BT=NULL;
	p=NULL;
	nlayer=1;
	printf("请输入插入的二叉树节点的数值(输入数字0结束节点赋值):\n");
	scanf("%d",&k.key);
	for(i=0;k.key!=NULL;i++)
	{		
		if(!SearchBST(BT,k.key,NULL,p))         //查找关键字
		{
			InsertBST(BT,k);                    //二叉树节点数值插入
			scanf("%d",&k.key);
		}
		else
		{
			printf("输入数据重复!\n");
			return 0;
		}
	}
	printf("二叉排序树树形输出为:\n");
	ShowBST(BT,nlayer);                        //树形显示二叉排序树
	printf("请输入删除的数据:");
	scanf("%d",&d.key);
	DeleteBST(BT,d.key);                       //删除关键字
	ShowBST(BT,nlayer);
	printf("先序遍历为:");                    //先序遍历、中序遍历、后序遍历
	PreOrderTraverse(BT,Visit);
	printf("\n中序遍历为:");
	InOrderTraverse(BT, Visit);
	printf("\n后序遍历为:");
	PostOrderTraverse(BT,Visit); 
	printf("\n清空该二叉排序树.\n");            //清空二叉树
	ClearBiTree(BT);
	ShowBST(BT,nlayer);
	printf("\n销毁该二叉排序树.\n");	        //销毁二叉树
	ClearBiTree(BT);
	
	return 0;
}


热门排行

今日推荐

热门手游