1. 程式人生 > >判斷給定序列是否為BST後序遍歷序列

判斷給定序列是否為BST後序遍歷序列

輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。假設輸入的陣列的任意兩個數字都互不相同。

目錄

一、BST

1.1 定義

1.2 性質

二、思路

一、BST

1.1 定義

BST(Binary Search Tree)二叉搜尋樹:

  1. 所有非葉子結點至多有兩個孩子(二叉搜尋樹也屬於二叉樹的範疇);
  2. 所有結點只儲存一個關鍵字;
  3. 非葉子結點的左指標指向小於其關鍵字的子樹,右指標指向大於其關鍵字的子樹;並且左右子樹也是BST。(如果出現等於的情況,放在左子樹部分和放在右子樹部分,不影響)。

1.2 性質

  1. 搜尋時,從根結點開始,如果查詢的關鍵字與根結點的關鍵字相等,那麼就命中;如果查詢的關鍵字比結點關鍵字小,就進入左子樹部分進行查詢;否則就需要進入右子樹部分進行查詢。查詢到最後也沒能找到,則報告找不到相應的關鍵字。
  2. 如果BST的所有非葉子結點的左右子樹的結點數目均保持差不多(平衡),那麼BST的搜尋效能逼近二分查詢,近似等於樹高(logn);但和連續空間的二分查詢相比,優點是:改變BST結構(插入或刪除操作)不需要移動大段的記憶體資料。
  3. 對BST樹進行中序遍歷,將會得到非遞減的序列。
圖1 常規BST示意圖

二、思路

後序遍歷BST得到的序列的性質是——最後一個元素x是根結點,以x為基準可將該序列(去掉x本身)劃分成兩個子序列,前一個子序列(左子樹)所有元素值均小於x;後一個子序列(右子樹)的所有元素值均大於x。前一個序列和後一個序列仍然滿足該性質。這是一個典型的遞迴求解的問題!

2.1 非遞迴版本

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int n = sequence.size();
        int i = -1;
        while(n > 1)    //只有1個結點的樹也是BST。
        { 
            //第一個迴圈體結束時,i指向右子樹序列開始位置;如果不存在右子樹——會指向根結點。
            while(sequence[++i] < sequence[n-1]);  
            
            //警惕陣列下標越界,第二個迴圈體正常結束,i將指向根結點的位置
            while(i < n-1 && sequence[i++] > sequence[n-1]);
            if(i < n-1) return false;
            i = 0;
            n--;
        }
        return n == 0 ? false : true;
    }
};
圖2 非遞迴版本牛客網執行結果