题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
思路
二叉搜索树的特点是:左子树的值比根节点小,右字数的值比根节点要大(不排除等于的情况)。利用搜索二叉树的特点,采用中序遍历二叉搜索树,其结果刚好等于从小到大对二叉树的结点进行排序。
如何中序遍历?我知道DFS遍历二叉树用到了栈,中序遍历也用到栈这个数据结构:有两个步骤:
1、如果栈顶元素非空且左节点存在,将其入栈,重复该过程。若不存在则进入第2步
2、若栈非空,输出栈顶元素并出栈。判断刚出栈的元素的右节点是否存在,不存在重复第2步,存在则将右节点入栈,跳至第1步
第二步解释一下:如果pop的结点有右子树,那么这个右子树中的所有结点的值都会比pop结点的父结点要小,相当于重新进入了一棵新的二叉搜索树,当然要重新走第一步啦~
时间复杂度
O(n)
代码
import java.util.Stack;
public class Solution {
TreeNode KthNode(TreeNode pRoot, int k)
{
//搜索二叉树的中序遍历就是排序结果
//中序遍历二叉树:
//1、如果栈顶元素非空且左节点存在,将其入栈,重复该过程。若不存在则进入第2步
//2、若栈非空,输出栈顶元素并出栈。判断刚出栈的元素的右节点是否存在,
//不存在重复第2步,存在则将右节点入栈,跳至第1步
if(pRoot == null)return null;
Stack<TreeNode> s = new Stack<TreeNode>();
s.push(pRoot);
int count = 0;
while(!s.isEmpty()){
while(s.peek().left!=null)
s.push(s.peek().left);
while(!s.isEmpty()){
TreeNode p = s.pop();
count ++;
if(count == k)
return p;
if(p.right!=null){
s.push(p.right);
break;
}
}
}
return null;
}
}