二叉搜索树的第k大的节点

题目

  给定一颗二叉搜索树,请找出其中的第k大的结点。

思路

  如果中序遍历一棵二叉搜索树,遍历序列的数值则是递增排序,因此只需中序遍历一个二叉搜索树即可。

  中序遍历用递归实现比较容易,但要想清楚的是遍历到一个根结点的时候要做的是什么?中序遍历二叉树打印的时候我们在递归完左子树之后打印根结点,本题目要求的当然不是打印,如果左子结点不是要找的结点,才会访问根结点,所以访问到根结点的时候要做的操作是将k减去1,因为左子结点已经证实不是要找的结点了,排除左子结点。这个过程可以看成目标移位的过程,每移过一个结点,K减1,直到K等于1时,当前结点就是要求的结点。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    TreeNode *kthLargestCore(TreeNode *root, int &k)
    {
        TreeNode *target = nullptr;//此处赋不赋值都可,因为到叶子结点会返回nullptr
        if (root->right != nullptr) {
            target = kthLargestCore(root->right, k);
        }
        if (target == nullptr) {//从叶节点返回的值为nullptr,依次向父节点返回该值,直到k==1,target值改变为当前节点的值
            if (k == 1) { //找到该节点后返回即可无需再次遍历
                target = root;
            }
            --k;
        }
        if (target == nullptr && root->left != nullptr) {
            target = kthLargestCore(root->left, k);
        }
        
        return target;
    }
public:
    int kthLargest(TreeNode* root, int k) {
        if (root == nullptr || k <= 0) {
            return 0;
        }

        TreeNode *res_node = kthLargestCore(root, k);
        return res_node != nullptr ? res_node->val : 0;
    }
};

 

posted on 2019-01-14 21:39  tianzeng  阅读(917)  评论(0编辑  收藏  举报

导航