二叉排序树

57 篇文章 1 订阅
52 篇文章 2 订阅

以二叉树或树作为表的组织形式,称为树表。树表在进行插入或删除操作时,可以方便地维护表的有序性,不需要移动表中记录,从而减少因移动记录引起的额外时间开销。常见的树表有二叉排序树、平衡二叉树、B-数和B+数等。
  二叉排序树(简称BST)的定义为:二叉排序树或者是空树,或者满足以下性质的二叉树:
  (a) 若它的左子树非空,则左子树上所有记录的值均小于根记录的值;
  (b) 若它的右子树非空,则右子树上所有记录的值均大于根记录的值;
  © 左右子树本身又各是一颗二叉排序树。
  二叉排序树的特点是:左小右大根居中,因此中序遍历一颗二叉排序树时,得到的是一个递增有序序列。
  二叉排序树通常采用二叉链存储结构进行存储,其结点的类型定义如下:

#define MaxSize 100
typedef int KeyType;
typedef char InfoType;
typedef struct node{
	KeyType key;         //关键字项
	InfoType data;       //其他数据域
	struct node *lchild,*rchild; //左右孩子指针
}BSTNode;

下面的代码演示建立二叉排序树、删除结点、查找某个值。

#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef int KeyType;
typedef char InfoType;
typedef struct node{
	KeyType key;         //关键字项
	InfoType data;       //其他数据域
	struct node *lchild,*rchild; //左右孩子指针
}BSTNode;

int path[MaxSize];
void DispBST(BSTNode *b);

//在BSTree中插入一个结点k
int InsertBST(BSTNode *&p,KeyType k){
	if (p==NULL)
	{
		p=(BSTNode *)malloc(sizeof(BSTNode));
		p->key=k; p->lchild=p->rchild=NULL;
		return 1;
	}
	else if(k==p->key)    //若相等,则不插入
		return 0;
	else if(k < p->key)
		return InsertBST(p->lchild,k);  //插入到p的左子树中
	else
		return InsertBST(p->rchild,k);  //插入到p的右子树中
}

//由数组A中的关键字建立一棵二叉排序树
BSTNode *CreatBST(KeyType A[],int n){
	BSTNode *bt=NULL;      //初始时bt为空树
	int i=0;
	while (i<n)
	{
		if (InsertBST(bt,A[i])==1)   //将A[i]插入到二叉排序树T中
		{
			printf("  第%d步,插入%d:",i+1,A[i]);
			DispBST(bt); printf("\n");
			i++;
		}
	}
	return bt;    //返回二叉排序树的根指针bt
}

//当被删*p结点有左右子树时的删除过程
void Delete1(BSTNode *p,BSTNode *&r){
	BSTNode *q;
	if(r->rchild!=NULL)
		Delete1(p,r->rchild);  //递归地找最右下结点
	else{                      //找到了最右下结点*r
		p->key=r->key;     //将*r的关键字值赋给*p
		q=r;
		r=r->rchild;       //将*r的双亲结点的右孩子改为*r的左孩子结点
		free(q);           //释放原*r的空间
	}

}

//从二叉排序树中删除*p结点
void Delete(BSTNode *&p){
	BSTNode *q;
	if (p->rchild==NULL)          //当*结点没有右子树时
	{
		q=p; p=p->lchild; free(q);
	}
	else if (p->lchild==NULL)   //当*p没有左子树时
	{
		q=p; p=p->lchild; free(q);
	}
	else Delete1(p,p->lchild);  //当*p结点既有左子树,又有右子树时
}

//在bt中删除关键字为k的结点
int DeleteBST(BSTNode *&bt,KeyType k){
	if(bt==NULL) return 0;
	else{
		if(k < bt->key)
			return DeleteBST(bt->lchild,k);
		else if( k > bt->key)
			return DeleteBST(bt->rchild,k);
		else{
			Delete(bt);
			return 1;
		}
	}
}

//以非递归方式输出从根结点到查找到的结点的路径
void SearchBST1(BSTNode *bt,KeyType k,KeyType path[],int i){
	int j;
	if(bt==NULL)
		return;
	else if (k==bt->key)
	{
		path[i+1]=bt->key;
		for(j=0;j<=i+1;j++)
			printf("%3d",path[j]);
		printf("\n");
	}
	else{
		path[i+1]=bt->key;
		if(k < bt->key)
			SearchBST1(bt->lchild,k,path,i+1);
		else
			SearchBST1(bt->rchild,k,path,i+1);
	}

}

//以递归方式输出从根结点到查找到的结点的路径
int SearchBST2(BSTNode *bt,KeyType k){
	if(bt==NULL)
		return 0;
	else if(k==bt->key)
	{
		printf("%3d",bt->key);
		return 1;
	}
	else if(k < bt->key)
		SearchBST2(bt->lchild,k);
	else
		SearchBST2(bt->rchild,k);
	printf("%3d",bt->key);

}

//以括号表示法输出二叉排序树bt
void DispBST(BSTNode *bt){
	if (bt!=NULL)
	{
		printf("%3d",bt->key);
		if (bt->lchild!=NULL || bt->rchild!=NULL)
		{
			printf("(");
			DispBST(bt->lchild);
			if(bt->rchild!=NULL) printf(",");
			DispBST(bt->rchild);
			printf(")");
		}
	}

}

KeyType predt=-32627;  //predt为全局变量,保存当前结点中序前趋的值,初值为-∞
int JudgeBST(BSTNode *bt){ //判断bt是否为BST
	int b1,b2;
	if(bt==NULL)
		return 1;
	else{
		b1=JudgeBST(bt->lchild);
		if(b1==0 || predt >= bt->key)
			return 0;
		predt=bt->key;
		b2=JudgeBST(bt->rchild);
		return b2;
	}

}

void main()
{
	BSTNode *bt;
	KeyType k=6;
	int a[]={4,9,0,1,8,6,3,5,2,7},n=10;
	printf(" 创建一棵BST树:");
	printf("\n");
	bt=CreatBST(a,n);
	printf(" BST:");DispBST(bt);printf("\n");
	printf(" bt%s\n",(JudgeBST(bt)?"是一棵BST":"不是一棵BST"));
	printf("\n");
	printf(" 查找%d关键字(递归):",k);SearchBST1(bt,k,path,-1);
	printf(" 查找%d关键字(非递归):",k);SearchBST2(bt,k);
	printf("\n 删除操作:\n");
	printf("   原BST:");DispBST(bt);printf("\n");
	printf("   删除结点4:");
	DeleteBST(bt,4);
	DispBST(bt);printf("\n");
	printf("   删除结点5:");
	DeleteBST(bt,5);
	DispBST(bt);
	printf("\n\n");
}

效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RWVAb3kf-1619603250794)(http://t1.qpic.cn/mblogpic/be1ac0678a5f991ae342/2000.jpg)]
图(1) 用括号表示法,输出二叉排序树
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值