1 題目描述
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 };
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 };
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 }
參考資料
https://blog.csdn.net/cdatreides/article/details/81701523
https://blog.csdn.net/lzuacm/article/details/51317617