C++ 判斷一顆樹是否是BST(二叉排序樹)
阿新 • • 發佈:2019-01-28
方法一:使用中序遍歷
因為二叉排序樹的中序遍歷結果是遞增的,所以可以通過中序遍歷儲存結果,再判斷是否為遞增的陣列。
1) 對樹進行中序遍歷,將結果儲存在b[]陣列中。
2) 檢測b[]陣列中元素是否為升序排列。如果是,則這棵樹為BST.
時間複雜度: O(n)
程式碼如下:
#include<iostream> #include<algorithm> using namespace std; typedef struct BinaryTreeNode{ int value; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; }BTNode; int max_height = -1; void addBTNode(BTNode *&myBT,int val);//新增節點 void createBT(BTNode *&BT,int arr[],int n);//建立二叉排序樹,通過*&來改變指標的值 void midorder_showBT(BTNode *myBT);//中序遍歷列印,如果是二叉排序樹,列印結果與單調遞增陣列一樣 int b[100]; int idx = 0; void is_BST(BTNode *myBT);//判斷是否是二叉排序樹 int main(){ BTNode *myBT = nullptr; int arr[10] = {314,426,12,78,143,8,21,14,9,314}; createBT(myBT,arr,10); midorder_showBT(myBT); cout<<endl; is_BST(myBT); bool isBT = true; if(idx == 1 || idx == 0) cout<<"是BST"<<endl; else{ for(int i=0;i < idx - 1;i++){ if(b[i] >= b[i+1]){ isBT = false; break; } } if(isBT) cout<<"是BST"<<endl; else cout<<"不是BST"<<endl; } return 0; } void is_BST(BTNode *myBT){ if(myBT == nullptr ) return ; is_BST(myBT->m_pLeft); b[idx++] = myBT->value; is_BST(myBT->m_pRight); } void createBT(BTNode *&BT,int arr[],int n){ BT = nullptr; for(int i=0;i<n;i++) addBTNode(BT,arr[i]); } void addBTNode(BTNode *&myBT,int val){ if(myBT == nullptr){ myBT = new BinaryTreeNode(); myBT->value = val; myBT->m_pLeft = nullptr; myBT->m_pRight = nullptr; return; } if(val == myBT->value){ return; } else if(val < myBT->value){ addBTNode(myBT->m_pLeft,val); } else{ addBTNode(myBT->m_pRight,val); } } void midorder_showBT(BTNode *myBT){//中序遍歷列印 { if(myBT == nullptr ) return; midorder_showBT(myBT->m_pLeft); cout<<myBT->value<<" "; midorder_showBT(myBT->m_pRight); }
方法二:限定二叉樹中節點值的範圍,優化演算法每個節點只需訪問一次
限定了子樹中節點值的範圍,從而每個節點只需訪問一次。節點值的初始範圍可限定為INT_MIN以及INT_MAX。
//判斷是否為BST
bool is_BT(BTNode *myBT,int min,int max){
if(myBT == nullptr || min > max)
return false;
return is_BT_Core(myBT,min,max);
}
//如果是一顆二叉查詢樹,且值範圍在[min,max],則返回true
bool is_BT_Core(BTNode *myBT,int min,int max);
程式碼實現如下:
#include<iostream> #include<algorithm> using namespace std; typedef struct BinaryTreeNode{ int value; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; }BTNode; int max_height = -1; void addBTNode(BTNode *&myBT,int val);//新增節點 void createBT(BTNode *&BT,int arr[],int n);//建立二叉排序樹,通過*&來改變指標的值 void midorder_showBT(BTNode *myBT);//中序遍歷列印,如果是二叉排序樹,列印結果與單調遞增陣列一樣 bool is_BT(BTNode *myBT,int min,int max);//判斷是否是BST(二叉排序樹) bool is_BT_Core(BTNode *myBT,int min,int max);//判斷是否是BST(二叉排序樹) 核心函式 int min_val = 1,max_val = 1000; int main(){ BTNode *myBT = nullptr; int arr[] = {314,426,12,78,143,8,21,14,9,314}; createBT(myBT,arr,sizeof(arr)/sizeof(arr[0])); cout<<"中序遍歷結果:"<<endl; midorder_showBT(myBT); cout<<endl; if(is_BT(myBT,min_val,max_val)){ cout<<"此二叉樹是BST"<<endl; }else cout<<"此二叉樹不是BST"<<endl; return 0; } bool is_BT(BTNode *myBT,int min,int max){ if(myBT == nullptr || min > max) return false;//空子樹返回false return is_BT_Core(myBT,min,max); } bool is_BT_Core(BTNode *myBT,int min,int max){ if(myBT == nullptr)//空結點時返回true結束 return true; //如果節點值違反了最大/最小約束條件,則不是BST if( (myBT->value < min) || (myBT->value > max) ) return false; return is_BT_Core(myBT->m_pLeft,min,myBT->value - 1) && is_BT_Core(myBT->m_pRight,myBT->value + 1,max); } void createBT(BTNode *&BT,int arr[],int n){ BT = nullptr; for(int i=0;i<n;i++) addBTNode(BT,arr[i]); } void addBTNode(BTNode *&myBT,int val){ if(myBT == nullptr){ myBT = new BinaryTreeNode(); myBT->value = val; myBT->m_pLeft = nullptr; myBT->m_pRight = nullptr; return; } if(val == myBT->value){ return; } else if(val < myBT->value){ addBTNode(myBT->m_pLeft,val); } else{ addBTNode(myBT->m_pRight,val); } } void midorder_showBT(BTNode *myBT){//中序遍歷列印 { if(myBT == nullptr ) return; midorder_showBT(myBT->m_pLeft); cout<<myBT->value<<" "; midorder_showBT(myBT->m_pRight); }
執行結果如下: