1. 程式人生 > >劍指Offer面試題:22.二叉搜尋樹的後序遍歷序列

劍指Offer面試題:22.二叉搜尋樹的後序遍歷序列

一、題目:二叉搜尋樹的後序遍歷序列

題目:輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則返回true,否則返回false。假設輸入的陣列的任意兩個數字都互不相同。

  例如在下面的一顆二叉搜尋樹中,輸入陣列{5,7,6,9,11,10,8},則返回true,因為這個整數序列是下圖二叉搜尋樹的後序遍歷結果。如果輸入的陣列是{7,4,6,5},由於沒有哪棵二叉搜尋樹的後序遍歷的結果是這個序列,因此返回false。

二、解題思路

2.1 核心步驟

  在後序遍歷得到的序列中,最後一個數字是樹的根結點的值。陣列中前面的數字可以分為兩部分:第一部分是左子樹結點的值,它們都比根結點的值小;第二部分是右子樹結點的值,它們都比根結點的值大

  因此,我們可以總結出演算法步驟:

  Step1.通過取出序列最後一個元素得到二叉搜尋樹的根節點;

  Step2.在二叉搜尋樹中左子樹的結點小於根結點,因此可以遍歷一次得到左子樹;

  Step3.在二叉搜尋樹中右子樹的結點大於根結點,因此可以繼續遍歷後序元素得到右子樹;

  Step4.重複以上步驟遞迴判斷左右子樹是不是二叉搜尋樹,如果都是,則返回true,如果不是,則返回false;

2.2 程式碼實現

    public static bool VerifySquenceOfBST(int[] sequence, int length)
    {
        
if (sequence == null || length <= 0) { return false; } int root = sequence[length - 1]; int i = 0; // 在二叉搜尋樹中左子樹的結點小於根結點 for (; i < length - 1; i++) { if (sequence[i] > root) {
break; } } // 在二叉搜尋樹中右子樹的結點大於根結點 int j = i; for (; j < length - 1; j++) { if (sequence[j] < root) { // 如果找到小於根節點直接返回false return false; } } // 判斷左子樹是不是二叉搜尋樹 bool leftIsBST = true; if (i > 0) { leftIsBST = VerifySquenceOfBST(sequence, i); } // 判斷右子樹是不是二叉搜尋樹 bool rightIsBST = true; if (j < length - 1) { // C#中無法直接操作指標,在C/C++可以直接傳遞sequence+i int[] newSequence = sequence.Skip(i).ToArray(); rightIsBST = VerifySquenceOfBST(newSequence, length - i - 1); } return leftIsBST && rightIsBST; }

三、單元測試

3.1 測試用例

    //            10
    //         /      \
    //        6        14
    //       /\        /\
    //      4  8     12  16
    [TestMethod]
    public void SequenceTest1()
    {
        int[] data = { 4, 8, 6, 12, 16, 14, 10 };
        bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
        Assert.AreEqual(result, true);
    }

    //           5
    //          / \
    //         4   7
    //            /
    //           6
    [TestMethod]
    public void SequenceTest2()
    {
        int[] data = { 4, 6, 7, 5 };
        bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
        Assert.AreEqual(result, true);
    }

    //               5
    //              /
    //             4
    //            /
    //           3
    //          /
    //         2
    //        /
    //       1
    [TestMethod]
    public void SequenceTest3()
    {
        int[] data = { 1, 2, 3, 4, 5 };
        bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
        Assert.AreEqual(result, true);
    }

    // 1
    //  \
    //   2
    //    \
    //     3
    //      \
    //       4
    //        \
    //         5
    [TestMethod]
    public void SequenceTest4()
    {
        int[] data = { 5, 4, 3, 2, 1 };
        bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
        Assert.AreEqual(result, true);
    }

    // 樹中只有1個結點
    [TestMethod]
    public void SequenceTest5()
    {
        int[] data = { 5 };
        bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
        Assert.AreEqual(result, true);
    }

    // 錯誤序列
    [TestMethod]
    public void SequenceTest6()
    {
        int[] data = { 7, 4, 6, 5 };
        bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
        Assert.AreEqual(result, false);
    }

    // 錯誤序列
    [TestMethod]
    public void SequenceTest7()
    {
        int[] data = { 4, 6, 12, 8, 16, 14, 10 };
        bool result = SequenceHelper.VerifySquenceOfBST(data, data.Length);
        Assert.AreEqual(result, false);
    }

    // 錯誤序列
    [TestMethod]
    public void SequenceTest8()
    {
        bool result = SequenceHelper.VerifySquenceOfBST(null, 0);
        Assert.AreEqual(result, false);
    }

3.2 測試結果

作者:周旭龍

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。

相關推薦

Offer試題22.搜尋序列

一、題目:二叉搜尋樹的後序遍歷序列 題目:輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則返回true,否則返回false。假設輸入的陣列的任意兩個數字都互不相同。   例如在下面的一顆二叉搜尋樹中,輸入陣列{5,7,6,9,11,10,8},則返回true,因為這個整數序列是

Offer試題25.搜尋與雙向連結串列

一、題目:二叉搜尋樹與雙向連結串列 題目:輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。比如輸入下圖中左邊的二叉搜尋樹,則輸出轉換之後的排序雙向連結串列。   二叉搜尋樹的節點定義如下,這裡使用C#語言描述:

offer 試題重建

題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。 思路:二叉樹先序是根左右,中序 是左根右。所以先找到

Offer試題23.中和為某一值的路徑

一、題目:二叉樹中和為某一值的路徑 題目:輸入一棵二叉樹和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。例如輸入下圖中二叉樹和整數22,則打印出兩條路徑,第一條路徑包含結點10、12,第二條路徑包含結點10、5和7。   二叉

offer試題的映象(遞迴、迴圈解法及測試用例)

題目:給定二叉樹,將其變換為源二叉樹的映象。 二叉樹的定義如下: struct TreeNode {     int val;     TreeNode* left;     TreeNode* right; }; 輸入描述: 二叉樹的映象定義:     源二叉樹    

Offer試題2.維陣列中的查詢

一、題目:二維陣列中的查詢 題目:在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。     例如下面的二維陣列就是每行、每列都遞增排序。如果在這個陣列中查詢數字7,則返回true;

牛客網線上程式設計專題《offer-試題39》的深度

題目連結: 題目描述: 解題思路: 解法:遞迴的遍歷一棵數的左右子樹。 已經AC的程式碼: public class treeDepth39 { public class Tr

offer試題7:重建(java實現)

題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹,假設輸入的前序遍歷和中序遍歷的結果都不含重複的數字。例如:輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6}則重建二叉樹:其中二叉樹的定義如下:  * publi

Offer試題6 重建

題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入的前序遍歷序列{1,2,4,7,3,5,6,8}和後序遍歷序列{4,7,2,1,5,3,8,6},則重建出如圖所示的二叉樹 二叉樹結點定義如下:

offer刷題記錄26——搜尋與雙向連結串列

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 public class Solution { public TreeNode Convert(TreeNode root) {

offer》給定一顆搜尋,請找出其中的第k大的結點。

題目:給定一顆二叉搜尋樹,請找出其中的第k大的結點。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按結點數值大小順序第三個結點的值為4。 解析:看到我寫的下面的程式碼,像一篇文章一樣的長,我也是醉了,先提交上去了。思想就是先來個層次遍歷二叉樹,得

Offer-Python-搜尋的後續序列

題目:二叉搜尋樹的後續遍歷序列 輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的陣列的任意兩個數字都互不相同。 思路:二叉搜尋樹的特點是,左子樹的值小於根節點的值,右子樹的值大於根節點的值。

搜尋的後續序列

題目 輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的陣列的任意兩個數字都互不相同。 程式碼 public boolean VerifySquenceOfBST(int [] sequence) {

搜尋C語言

  層序遍歷,寫完了,感慨下.   不同於前序遍歷,中序遍歷,後序遍歷,層序遍歷沒有使用棧模式,而是使用了佇列.   佇列中的資料,即QueueItem是二叉搜尋樹結點指標,這樣可以儲存結點,並且可以方便處理棧為空時返回值的問題.也就是可以返回NULL.   用一個函式實現,

Offer試題21.從上到下列印

一、題目:從上到下列印二叉樹 題目:從上往下打印出二叉樹的每個結點,同一層的結點按照從左到右的順序列印。例如輸入下圖中的二叉樹,則依次打印出8、6、10、5、7、9、11。   二叉樹節點的定義如下,採用C#語言描述: public class BinaryTreeNode

Offer試題7 用個棧實現佇列

題目:用2個棧實現一個佇列。佇列的宣告如下,請實現它的兩個函式appendTail和deleteHead,分別完成在佇列尾部插入結點和在佇列頭部刪除結點的功能。 佇列的宣告: template <typename T> class CQueue { publi

offer 試題從尾到頭列印連結串列

題目:輸入一個連結串列,按連結串列值從尾到頭的順序返回一個ArrayList。 思路:有多種放法。(1)先反轉連結串列,再列印連結串列。(2)使用棧。 /** * struct ListNode { * int val; * struct ListNode *n

Offer試題17.的子結構

一、題目:樹的子結構 題目:輸入兩棵二叉樹A和B,判斷B是不是A的子結構。例如下圖中的兩棵二叉樹,由於A中有一部分子樹的結構和B是一樣的,因此B是A的子結構。   該二叉樹的節點定義如下,這裡使用C#語言描述: public class BinaryTreeNode {

Offer試題31.兩個連結串列的第一個公共節點

一、題目:兩個連結串列的第一個公共節點 題目:輸入兩個連結串列,找出它們的第一個公共結點。   連結串列結點定義如下,這裡使用C#語言描述: public class Node { public int key; public Node

Offer試題14.連結串列的倒數第k個節點

PS:這是一道出境率極高的題目,記得去年參加校園招聘時我看到了3次,但是每次寫的都不完善。 一、題目:連結串列的倒數第k個節點 題目:輸入一個連結串列,輸出該連結串列中倒數第k個結點。為了符合大多數人的習慣,本題從1開始計數,即連結串列的尾結點是倒數第1個結點。例如一個連結串列有6個結點,從頭結點開始