题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如,(5,3,7,2,4,6,8)中,按结点数值大小顺序第三小结点的值为4。
思路
采用递归的方式,不断递归深入根节点的左孩子,直到碰到空节点为止,然后回溯输出当前节点。再以同样的方式递归遍历其右孩子。在此期间,每访问一个节点,我们都对k进行减一操作,直到k为0,说明该节点即为第k个节点。
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的时候,当前结点就是第m小
if(--m > 0) dfs(p -> right);// 右子树同样处理/遍历该节点的右节点 (左中右)
}
TreeNode* KthNode(TreeNode* p, unsigned int k){
ans = NULL; m = k;//初始化 ans=NULL 不满足条件返回NULL
dfs(p);
return ans;
}
};
非递归版中序遍历,可以利用栈来模拟递归遍历,首先根入栈,然后令根节点的左孩子不断入栈直到为空,弹出栈顶,令其右孩子入栈,重复以上操作,直到遍历结束或者访问第k个节点为止。
class Solution {
public:
TreeNode* KthNode(TreeNode* pRoot,unsigned 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;
}
};