二叉排序树的相关算法

1. 判断给定的二叉树是否是二叉排序树

利用中序遍历,若始终能保持前一个值比后一个值小,则是二叉排序树。

int predt = -32767;	//中序前驱的值

int JudgeBST(BiTree bt){
	int left, right;
	if(bt == NULL)	//空树
		return 1;
	else {
		left = JudgeBST(bt->lchild);	//判断左子树
		if(left == 0 || predt >= bt->data)	//左子树返回0或前驱大于等于当前结点(中序)
			return 0;
		predt = bt->data;
		right = JudgeBST(bt->rchild);	//判断右子树
		return right;
	}
}

2. 求出指定结点在给定二叉排序树中的层次

在二叉排序树中,查找一次就下降一层。因此查找该结点所用次数就是层次。

int level(BiTree bt, BSTNode *p){
	int n = 0;	//统计查找次数
	BiTree t = bt;
	if(bt != NULL){
		n++;
		while(t->data != p->data){
			if(t->data < p->data)	//查左子树
				t = t->lchild;
			else
				t = t->rchild;
			n++;					//层次加1
		}
	}
	return n;
}

3. 从大到小输出二叉排序树中所有值不小于k的关键字

由二叉排序树的性质,右子树>根>左,采用右根左的遍历方式。

void OutPut(BSTNode *bt, int k){
	if(bt == NULL)
		return;
	if(bt->rchild != NULL)
		OutPut(bt->rchild, k);
	if(bt->data >= k)
		printf(%d\t”, bt->data);
	if(bt->lchild != NULL)
		OutPut(bt->lchild, k);
}

4. 判断二叉树是否是平衡二叉树

  1. 空树,高度0,平衡
  2. 仅有根结点,高度1,平衡
  3. 否则,递归判断左右子树,返回左右平衡标记blbr,高度为最高子树的高度加1,且左右都平衡时才平衡
void Judge_AVL(BiTree bt, int &balance, int &h){
	int b1 = 0, br = 0, hl = 0, hr = 0;	//左、右子树的平衡标记和高度
	if(bt == NULL){	//空树
		h = 0;
		balance = 1;
	} else if(bt->lchild == NULL && bt->rchild == NULL){	//仅有根结点
		h = 1;
		balance = 1;
	} else {
		Judge_AVL(bt->lchild, bl, hl);	//判断左子树
		Judge_AVL(bt->rchild, br, hr);	//判断右子树
		h = (hl > hr ? hl : hr) + 1;	//当前分支最大高度加1
		if(abs(hl - hr) < 2)
			balance = bl && br;
		else
			balance = 0;
	}
}

5. 删除二叉排序树中结点值小于或等于x的全部结点

  • (1)若bt->data <= x,将bt指向bt的右孩子,并删除根结点bt及bt的左子树的全部结点,重复,直到bt->data > x为止
  • (2)沿bt的左分支搜索,直到左分支结点的data值小于等于x,回到(1)继续删除。
  • 重复(1)、(2),直到左子树为空
void delSubTree(BSTNode *p){		//删除以p为根结点的子树的全部结点
	if(p != NULL){
		delSubTree(p->lchild);
		delSubTree(p->rchild);
		free(p);
	}
}

void del_eqorlsix(BSTNode *bt, int x){
	BSTNode *p, *pr = NULL;
	while(bt != NULL){
		while(bt != NULL && bt->data <= x){		//第一种情况
			p = bt;
			bt = bt->rchild;
			delSubTree(p->lchild);				//删除根结点的左子树
			free(p);							//删除根结点
			if(pr != NULL)
				pr->lchild = bt;
		}
		while(bt != NULL && bt->data > x){		//第二种情况
			pr = bt;
			bt = bt->lchild;
		}
	}
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Beta Lemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值