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. 判断二叉树是否是平衡二叉树
- 空树,高度0,平衡
- 仅有根结点,高度1,平衡
- 否则,递归判断左右子树,返回左右平衡标记
bl
、br
,高度为最高子树的高度加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;
}
}
}