在二叉排序樹上面找出第3大的節點

題目:
在二叉排序樹上面找出第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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章