题目:
在二叉排序树上面找出第3大的节点。
注意:不能把二叉树全量存储到另外的存储空间,比如存储到数组中,然后取出数组的第三个元素。
- 递归解法
import java.util.Stack;
public class Problem3 {
private static int count = 0;
public static void main(String[] args) {
TreeNode node1 = new TreeNode(1, null, null);
TreeNode node3 = new TreeNode(3, null, null);
TreeNode node4 = new TreeNode(4, node3, null);
TreeNode node2 = new TreeNode(2, node1, node4);
TreeNode node8 = new TreeNode(8, null, null);
TreeNode root = new TreeNode(6, node2, node8);
System.out.println("递归求解");
TreeNode result1 = find1(root);
if (result1 != null) {
System.out.println(result1.value);
} else {
System.out.println("result1 is null");
}
System.out.println("非递归求解");
TreeNode result2 = find2(root);
if (result2 != null) {
System.out.println(result2.value);
} else {
System.out.println("result2 is null");
}
}
public static class TreeNode {
int value;
TreeNode left, right;
public TreeNode(int value, TreeNode left, TreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
};
/*
* 对二叉排序树进行中序遍历可以得到从小到大的序列
* 中序遍历递归实现: 先中序遍历左子树,然后遍历根节点,中序遍历右子树
* 本题解法:
* 使用逆序中序遍历可以较快地得到第三大的元素
* 先逆中序遍历右子树,再读取根结点,再逆序遍历左子树
*/
//递归写法
private static TreeNode find1(TreeNode root) {
if (root != null) {
TreeNode r1 = find1(root.right);
if(r1 != null) {
//已找到第三最大
return r1;
}
if(count++ == 2) {
return root;
}
TreeNode r2 = find1(root.left);
if(r2 != null) {
//已找到第三最大
return r2;
}
}
return null;
}
//非递归写法
private static TreeNode find2(TreeNode root) {
//二叉树逆中序遍历,右中左
//需要借助一个栈
Stack<TreeNode> s = new Stack<>();
TreeNode p = root;//工作指针
int count2 = 0;//用于寻找第三大,计数器
while(p !=null || !s.isEmpty()){
//栈非空或者p非空时循环
if(p != null){
s.push(p);//根指针进栈
p = p.right;//遍历右子树
}else{
p = s.pop();//退栈并访问
if(count2++ == 2){
// System.out.println(p.value);
return p;
}
p = p.left;//遍历左子树
}
}
return null;
}
}