拓展 :二叉排序树相关

1、判断一棵二叉排序树是否是平衡二叉树

2、判断一棵树是否是一棵二叉排序树

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

4、求解二叉排序树中第 k 小的元素

/**
 * 拓展 :二叉排序树相关
 *
 * ①算法思想
 * 1、判断一棵二叉排序树是否是平衡二叉树
 * 平衡二叉树是左右子树高度差不大于 1 的树,通过 GetHeight函数得到左右子树高度,那这个函数来改。
 *
 * 2、判断一棵树是否是一棵二叉排序树
 * !!!但凡遇到二叉排序树的习题,一定是用中序遍历来考虑!!!因为中序序列是一个递增的。
 * 只要保证中序序列是一个递增的,那么这个二叉树就是二叉排序树。
 * 设置一个pre和一个p,做一个中序遍历,如果pre -> data > p -> data,就说明出错了,不满足构成二叉排序树的条件。
 * 否则就pre = p,这样依次遍历直到结束。
 *
 * 3、从大到小输出二叉排序树中所有不小于 k 的关键字
 * 方法一:中序遍历 + 辅助栈
 * 先中序遍历将不小于 k 的数从小到大进行压栈;
 * 然后弹栈就可以得到从大到小的序列了。
 * 方法二:逆中序遍历
 * 中序遍历是左中右,输出是从小到大,
 * 逆中序遍历是右中左,输出是从大到小。
 * (只要将中序中的 lchild 和 rchild 的位置交换一下就变成了逆中序)
 * 
 * 4、求解二叉排序树中第 k 小的元素
 * 首先要求出这棵树一共有多少个节点,左子树节点数之和 + 右子树节点数之和 + 1 就是这棵树的节点数。
 * 求出左子树的节点个数,如果 k 小于左子树节点个数的话,说明在左子树之中;
 * 如果等于左子树节点个数 + 1 的话,说明是根节点;
 * 如果大于左子树个数 + 1 的话,说明在右子树之中,在右子树之中就是第 k - 左子树节点个数 - 1 小。
 *
 * ②算法设计
 */


#include <stdio.h>
#include <iostream>
#define MaxSize 100

typedef struct BiTreeNode{
    int data;
    BiTreeNode *lchild,*rchild;
}BiTreeNode,*BiTree;


//1、判断一棵二叉排序树是否是平衡二叉树
int GetHeightNR(BiTree T){
    if(T == NULL)
        return 0;
    int left = GetHeightNR(T -> lchild);
    int right = GetHeightNR(T -> rchild);
    return left > right ? left + 1 : right + 1;
}

int IsBalanceTree(BiTree T,int &IsBalance){//刚开始IsBalance设置为true
    if(T == NULL)
        IsBalance = true;
    int left = GetHeightNR(T -> lchild);
    int right = GetHeightNR(T -> rchild);
    if(abs(left - right) > 1)
        IsBalance = false;
}

//2、判断一棵树是否是一棵二叉排序树
void IsSortTree(BiTree pre,BiTree p,int &IsSort){
    if(p != NULL){
        IsSortTree(pre,p -> lchild,IsSort);
        if(pre == NULL){
            pre = p;
        }else{
            if(pre -> data >= p -> data){
                IsSort = false;
                pre = p;
            }
        }
        IsSortTree(pre,p -> rchild,IsSort);
    }
}

//3、从大到小输出二叉排序树中所有不小于 k 的关键字
//方法一:中序遍历 + 辅助栈
void PrintfGTK(BiTree T,int k,int *stack,int &top){//top初值为 -1
    if(T){
        PrintfGTK(T -> lchild,k,stack,top);
//        Visit(T);
        if(T -> data >= k)
            stack[++top] = T -> data;
        PrintfGTK(T -> rchild,k,stack,top);
    }
}
void PrintResult(BiTree T,int k) {
    int *stack = (int *) malloc(sizeof(int) * MaxSize);
    int top = -1;
    PrintfGTK(T, k, stack, top);
}
//方法二:逆中序遍历
void PrintfGTK(BiTree T,int k){
    if(T != NULL){
        PrintfGTK(T -> rchild,k);
//        Visit(T);
        if(T -> data >= k)
            printf("%d ",T -> data);
        PrintfGTK(T -> lchild,k);
    }
}

//4、求解二叉排序树中第 k 小的元素
//首先求解节点个数
int number(BiTree T){
    if(T == NULL)
        return 0;
    else
        return number(T -> lchild) + number(T -> rchild) + 1;
}
//然后求第 k 小的元素
BiTree FindK(BiTree T,int k){
    int leftnum = number(T -> lchild);
    if(leftnum >= k)
        FindK(T -> lchild,k);
    else if(leftnum + 1 == k)
        return T;
    else
        return FindK(T -> rchild,k - leftnum - 1);
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值