题目描述:
给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
思路:
二叉搜索树的中序遍历其实就是其中各个节点按照从小到大的顺序进行排序。因此可以考虑使用二叉树中序遍历的方法来解此题。详细可参考二叉树中序遍历的递归与非递归写法。二叉树的中序遍历分为递归与非递归两种方式。无论采用哪种方式都需要设置好一个计数器用于记录遍历的点数,一旦到达相应的点数则返回该结点。
递归方式:
//定义索引用于记录走过的点数
private int index = 0;
private TreeNode node = null;
//递归方式
public TreeNode KthNode(TreeNode pRoot, int k){
//判断是否为空
if(pRoot == null || k == 0){
return null;
}
return getResult(pRoot, k);
}
//获取结果节点
public TreeNode getResult(TreeNode pRoot,int k){
if(pRoot.left != null){
node = getResult(pRoot.left, k);
}
index++;;
if(index == k){
return pRoot;
}
if(pRoot.right != null){
node = getResult(pRoot.right, k);
}
return node;
}
非递归方式:
TreeNode KthNode(TreeNode pRoot, int k) throws InstantiationException, IllegalAccessException {
//判断是否为空
if(pRoot == null || k == 0){
return null;
}
TreeNode p = pRoot;
TreeNode resultpoint = null;
//计数器用于记录是否达到了k的点数
int count = 0;
//新建一个栈用于记录二叉排序树中序遍历的点数
ArrayList<TreeNode>stack1 = new ArrayList<TreeNode>();
while(p != null || !stack1.isEmpty()){
while(p != null){
stack1.add(p);
p = p.left;
}
if(!stack1.isEmpty()){
count++;
p = stack1.remove(stack1.size()-1);
if(count == k){
resultpoint = p;
break;
}
p = p.right;
}
}
return resultpoint;
}