1. 程式人生 > 其它 >演算法筆記-判斷是否二叉搜尋樹

演算法筆記-判斷是否二叉搜尋樹

  二叉搜尋樹定義:二叉查詢樹(Binary Search Tree),(又:二叉搜尋樹,二叉排序樹)它或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;

  我們來看一下定義:左子樹小於父節點小於右子樹,這咋和我之前的二叉樹中序遍歷一樣的呢,通俗解釋:二叉樹中序遍歷是有序增長的。

  這樣就簡單了啊,我都遍歷出來了,遍歷的時候順帶比較一下前後大小是否一一增長不就行了嗎,程式碼:

/**
     * 中序遍歷
     * @param head
     */
    public
static boolean inOrderUnRecur(Node head) { if(head != null) { Stack<Node> stack = new Stack<>(); int pre= Integer.MIN_VALUE; while(!stack.empty() || head != null){ if(head != null){ stack.push(head); head
= head.left; }else{ head = stack.pop(); if(head.value < pre){ return false; } pre = head.value; head = head.right; } } System.out.println(); }
return true; }

這裡我增加了一個變數,記錄一下前置節點的值,在原來列印的地方比較一下是否完全符合增長邏輯,一旦不符合直接返回失敗,這是非遞迴方式的修改,遞迴方式的要複雜一點:

public static boolean inOrderRecur(Node head) {

        boolean[] isBST = new boolean[1];
        isBST[0] = true;
        inOrderRecur(head,new int[]{Integer.MIN_VALUE},isBST);
        return isBST[0];
    }

    /**
     * 中序遍歷
     * @param head
     */
    public static void inOrderRecur(Node head, int[] pre, boolean[] isBST) {
        if (head == null) {
            return;
        }
        inOrderRecur(head.left,pre,isBST);
        System.out.print(head.value + " ");
        if(pre[0] > head.value){
            isBST[0] = false;
        }
        pre[0] = head.value;
        inOrderRecur(head.right,pre,isBST);
    }

道理是差不多的,只不過我多加了一個標識是否是搜尋樹,這裡前置節點pre一開始我用的是int變數,後來測試發現有問題,又理了一遍,發現如下圖所示2和7所在的節點其實都是使用left節點遞迴進入的,雖然我修改了pre的值,但是回到節點2其實還是初始的值,因此必須使用一個全域性變數形式的值來儲存,因此改為陣列形式或者任意形式的全域性唯一變數都可以。