【剑指offer】二叉搜索树的第k个结点

拥有回忆 提交于 2020-02-08 02:21:10

题目描述

给定一棵二叉搜索树,请找出其中的第k小的结点。例如,(5,3,7,2,4,6,8)中,按结点数值大小顺序第三小结点的值为4。

解题思路

首先,二叉搜索树有一个很好的特性,任意一个结点必大于其左子树的所有结点,必小于等于其右子树的所有结点。如果使用中序遍历二叉搜索树,那么结果会按数值从小到大的顺序输出。

<图>

例如上图就是一棵二叉搜索树。中序遍历上图的二叉搜索树,输出结果为:1,3,4,6,7,8,10,13,14。

所以自然地我们就产生了一个解决方法,就是使用中序遍历二叉搜索树,记录输出个数,如果输出个数等于目标 k,则返回该结点即可。

这里使用非递归的方法实现中序遍历,以便记录输出个数。使用栈来存储结点,先扫描根结点的所有左结点,并将它们放进栈,直至左结点为空,然后取出栈顶结点,访问栈顶结点,再扫描该结点的右结点,将其进栈,再扫描这个右结点的所有左结点并进栈,如此继续,直到栈空。

(PS:博客《二叉树的中序遍历非递归算法》中用图展示了中序遍历的非递归算法,比较直观。另一篇 博客 则展示了二叉树的三种遍历方法递归及非递归的实现代码。)

实现代码:

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        if(!pRoot){
            return NULL;
        }
        stack<TreeNode*> nodes;
        TreeNode* p = pRoot;
        int count = 0;
        while(p|| !nodes.empty()){
            if(p){
                nodes.push(p);
                p = p->left;
            }else{
                p = nodes.top();
                count++;
                if(count==k){
                    break;
                }
                nodes.pop();
                p = p->right;
            }
        }
        return p;
    }
};

参考链接:
1.https://blog.csdn.net/billy1900/article/details/86229656
2.https://www.jianshu.com/p/2b4a58bf48ad

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!