题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
方法一:递归方法
这个方法的思路是先将指针移到最左端,然后再回溯,这个时候需要添加对右字符的遍历。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
int m;
TreeNode* ans;
void dfs(TreeNode* p){
if(!p || m < 1) return;// 不满足条件直接返回null/每次递归出口
dfs(p->left);//走到了最左边节点,到空不继续递归,该节点左右走完了回溯上一层
if(m == 1) ans = p;// 最左边节点 / m-1到1的时候,当前节点就是第m小
if(--m > 0) dfs(p->right);//右子树同样处理 /遍历该节点的右节点(左中右)
}
TreeNode* KthNode(TreeNode* pRoot, int k)
{
ans = NULL; m = k; // 初始化 ans=NULL, 不满足条件返回NULL
dfs(pRoot);
return ans;
}
};
方法二:非递归方法
/*
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* p = pRoot;
while(!res.empty() || p){//res是空 and遍历到空节点
while(p){
res.push(p);
p = p->left;
}
TreeNode* node = res.top();
res.pop();
if((--k) == 0) return node;
p = node->right;
}
return nullptr;
}
};