题意思路:
给定一棵二叉搜索树,请找出其中的第k小的TreeNode结点。
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树:

若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

它的左、右子树也分别为二叉排序树。

方法一:中序递归遍历二叉树
中序递归就是二叉搜索树的第个结点;

若二叉树为空则结束返回,否则:

(1)中序遍历左子树

(2)访问根结点

(3)中序遍历右子树

通过搜索顺序寻找第个结点

复杂度分析

时间复杂度:O(),表示二叉树结点数量,递归中序遍历所有结点。

空间复杂度:O(),递归开辟新空间。

图文详解:

图片说明

/*
struct TreeNode {//定义二叉树
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    TreeNode* res;
    void inorder(TreeNode* root,int &k){
        if(root==nullptr)return ;//如果当前结点为空返回
        inorder(root->left,  k);//递归遍历左子树
        k--;//枚举第i个结点
        if(k==0) res=root;
        inorder(root->right,  k);//递归遍历右子树
    }
    TreeNode* KthNode(TreeNode* pRoot, int k) {
       inorder(pRoot,k);//递归中序遍历
        return res;
    }


};

方法二:非递归中序遍历二叉树

通过栈来非递归模拟二叉树的中序遍历

沿着左子树一直加入栈中

取栈顶结点访问

对当前栈顶结点的右子树进行同样方式的访问

复杂度分析

时间复杂度:O(),表示二叉树结点数量,非递归中序遍历所有结点。

空间复杂度:O(),所有结点可能会全部入栈。

/*
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 nullptr;//特判根结点为空时
        stack<TreeNode*>res;//用栈模拟非递归
        TreeNode* head=pRoot;
        while(res.size()||head){//如果当前栈内不为空或者结点当前有值
            while(head){//当前结点不为空时
                res.push(head);//将其左子树加入栈中
                head=head->left;
            }
            TreeNode* node =res.top();//弹出栈顶结点
            res.pop();
            if(--k==0)return node;//枚举第k小结点
              head=node->right;//当前结点等于右子树
        }
        return nullptr;
    }


};