二叉排序树经典题目

leetcode 110

题目

思路

由题目中二叉排序树的结构定义中没有高度的成员,所以我们需要自己求出每个子节点的高度,这里我们采用递归思路,并在递归的回溯过程中求每个节点的左右子树的高度,同时也求出高度差,当高度差大于1时,退出返回。

解题代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

/**
 *   int getHeight(struct TreeNode *root)
 *   描述:求二叉排序树的高度,若某个节点的左右子树高度差大于1时,该函数返回-1,否则返回高度差。
 *   返回值:返回值只有三种情况: 0 1 -1,其中0 1表示该二叉排序树的高度差为0或者1,-1表示该二叉排序树的高度差大于1.
 *   参数: root 二叉排序树的根节点 
 */
int getHeight(struct TreeNode *root) {
    if (root == NULL) {
        return 0;//递归终点,在这里返回高度0.
    }
    int l = getHeight(root->left);//向左递归,求左子树的高度
    int r = getHeight(root->right);//向右递归,求右子树的高度
    if (l == -1 || r == -1) return -1;//每次求出当前节点的左右子树的高度后,必须判断左右子树是否失衡了,失衡了直接返回-1
    if (abs(l - r) > 1) return -1;//判断当前节点的左右子树的高度差是否超过1,超过1则返回-1,表示当前节点失衡了。
    return ((l > r ? l : r) + 1);//当前节点没有失衡,则求出当前节点的高度。
}

bool isBalanced(struct TreeNode* root){
    return getHeight(root) >= 0;
}

剑指 Offer 54

题目

image

思路

因为二叉排序树中序遍历可以得到节点key的升序的序列,其中中序遍历是采用递归的形式先遍历左子树,然后再打印根节点,最后遍历右子树,这样由于二叉排序树的性质,左子树的节点比根节点小,右子树的节点比根节点大,这样就确保遍历出来的序列是升序,但是由于本题目求的是第K大节点,我们可以采用中序遍历的思想,只是过程是先遍历右子树,然后再输出根节点,最后遍历左子树,这样就可以确保得到的序列是降序的了。

解题代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int ans = 0, n;
/**
 *  void in_order(struct TreeNode *root)
 *  描述:以右子树,根节点,左子树的方式遍历二叉排序树,找出第K大节点
 */
void in_order(struct TreeNode *root) {
    if (root == NULL) {
        return ;//递归终点,开始回溯
    }
    in_order(root->right);//递归右子树
    n--;//回溯到根节点时,n值减一
    if (n == 0) {//n值为0,则找到了第K大节点,返回
        ans = root->val;
        return ;
    }
    in_order(root->left);
}

int kthLargest(struct TreeNode* root, int k){
    if (root == NULL) {
        return 0;
    }
    n = k;
    in_order(root);
    return ans;
}
原文地址:https://www.cnblogs.com/ydqblogs/p/14929564.html