題目描述:
給定一顆二叉搜索樹,請找出其中的第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;
}