劍指offer23:輸入一個整數數組,判斷該數組是不是某二叉搜索樹的后序遍歷的結果。輸出Yes OR No。


  

1 題目描述

  輸入一個整數數組,判斷該數組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。

2 思路和方法

  二叉搜索樹:二叉查找樹(Binary Search Tree),(又:二叉搜索樹,二叉排序樹)它或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 它的左、右子樹也分別為二叉排序樹。

  遞歸求解:

(1)從第0位開始,找到第一位比根節點大的元素,記錄此位置i。在此位置之前都屬於左子樹(此時已經斷定左子樹都小於根節點)

(2)檢查右子樹是否都大於跟節點(從第i位開始,到根節點前)

(3)判斷左右子樹是否都屬於二叉搜索樹。

二叉查找樹相比於其他數據結構的優勢在於查找、插入的時間復雜度較低,為O(log n)。二叉查找樹是基礎性數據結構,用於構建更為抽象的數據結構,如集合、multiset、關聯數組等。

非遞歸求解:

       6
      /      \
    3         8
  /   \      /   \
2     5    7    9

2 5 3 7 9 8 6

  左子樹一定比右子樹小,因此去掉根結點后,數字分為left,right兩部分,right部分的最后一個數字是右子樹的根,且它比左子樹所有結點的值大,因此我們可以每次只看有子樹是否符合條件即可,即使到達了左子樹,左子樹也可以看出由左右子樹組成的樹還像右子樹那樣處理.

3 C++核心代碼

3.1 遞歸求解

 1 class Solution {
 2 public:
 3     bool VerifySquenceOfBST(vector<int> sequence) {}    //判斷某數組是不是二叉搜索樹的后序遍歷序列
 4         if(sequence.empty())
 5             return false;
 6         int index;
 7         int begin = 0;
 8         int end = sequence.size()-1;
 9         int root = sequence[end];    
10         for(index = begin;index<end;index++)    //左子結點小於根節點
11             if(sequence[index]>root)
12                 break;
13         for(int j = index;index<end;index++)    //右子結點大於根結點
14             if(sequence[index]<root)
15                 return false;
16         bool left = true;
17         vector<int> left_sq(sequence.begin(),sequence.begin()+index);
18         if(index>begin)
19             left = VerifySquenceOfBST(left_sq);    //判斷左子樹是不是二叉搜索樹
20         bool right = true;
21         vector<int> right_sq(sequence.begin()+index+1,sequence.end());
22         if(index<end-1)
23             right = VerifySquenceOfBST(right_sq);    //判斷右子樹是不是二叉搜索樹
24         return left&&right;
25     }
26 };
View Code

3.2 非遞歸求解

 1 class Solution {
 2 public:
 3     bool VerifySquenceOfBST(vector<int> sequence) {    //判斷某數組是不是二叉搜索樹的后序遍歷序列
 4         int backIdx = sequence.size();
 5         if(backIdx==0) return false;
 6 
 7         int forIdx = 0;
 8         while(--backIdx)  // backIdx=1時退出循環
 9         {
10             while(sequence[forIdx]<sequence[backIdx])  forIdx++;     // forIdx從前往后掃描left部分
11             while(sequence[forIdx]>sequence[backIdx])  forIdx++;     // forIdx從前往后繼續掃描,主要掃right部分
12 
13             if(forIdx<backIdx) return false;    // 如果原序列是二叉搜索樹BST的后序遍歷序列,則終止時forIdx=backIdx
14             forIdx=0;                           // 將forIdx拉回序列起點繼續掃
15         }
16         return true;
17     }
18 };
View Code

4 C++完整代碼

 1 #include<cstdio>
 2 #include<vector>
 3 
 4 using namespace std;
 5 
 6 class Solution{
 7 public:
 8     bool VerifySquenceOfBST(vector<int> sequence)
 9     {
10         int len = sequence.size();
11         if (len <= 0) 
12             return false;
13         vector<int> left, right;
14         int root = sequence[len - 1];
15         int i = 0;
16         while (i<len - 1)  // 處理left部分 
17         {
18             if (sequence[i]>root) 
19                 break;
20             left.push_back(sequence[i]);
21             i++;
22         }
23         int j = i; // 處理right部分,此時i為left部分最后一個結點的下標 
24         while (j<len - 1)
25         {
26             if (sequence[j]<root) 
27                 return false;
28             right.push_back(sequence[j]);
29             j++;
30         }
31         bool bleft = true; // 應初始化為true,left部分是BST序列,才能調用VerifySquenceOfBST()    
32         if (i != 0) 
33             bleft = VerifySquenceOfBST(left); // i為left部分最后一個結點的下標 ,i!=0表示有左子樹 
34         bool bright = true;
35         if (i != len - 1) 
36             bright = VerifySquenceOfBST(right);  // i!= len-1表示有右子樹
37         return (bleft && bright);
38     }
39 };
40 // 以下為測試部分 
41 int main()
42 {
43     Solution sol;
44     vector<int> vec1 = { 2, 5, 3, 7, 9, 8, 6 };
45     vector<int> vec2 = { 5, 7, 6, 9, 11, 10, 8 };
46     vector<int> vec3 = { 7, 4, 6, 5 };
47     bool res1 = sol.VerifySquenceOfBST(vec1);
48     bool res2 = sol.VerifySquenceOfBST(vec2);
49     bool res3 = sol.VerifySquenceOfBST(vec3);
50 
51     printf("%d\n", res1);
52     printf("%d\n", res2);
53     printf("%d\n", res3);
54 
55     system("pause");
56     return 0;
57 }
View Code

參考資料

https://blog.csdn.net/cdatreides/article/details/81701523

https://blog.csdn.net/lzuacm/article/details/51317617


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM