二叉排序樹(Binary Sort Tree),又稱二叉查找樹。node
一、若左子樹不爲空,則左子樹上全部結點的值均小於他的根結構的值;ios
二、若右子樹不爲空,則右子樹上全部結點的值均大於他的根結構的值;數組
三、他的左、右子樹也分別爲二叉排序樹。ide
使用中序遍歷時,二叉排序樹的輸出順序是由小到大的有序數列。函數
二叉排序樹類的: C++ 實現:測試
#include<iostream> using namespace std; template<class T> struct TreeNode { T element; TreeNode<T>*parent, *lnode, *rnode; TreeNode(){ parent = lnode = rnode = NULL; } TreeNode(const T& key) { element = key; parent = lnode = rnode = NULL; } }; template<class T> class BStree { public: BStree() :root(NULL){} //獲取根結點 TreeNode<T>* Getroot(){ return root; } //中序遍歷 void Inorder(TreeNode<T>*node); //遞歸查找 TreeNode<T>* TreeSearch(TreeNode<T>*node, T key); //迭代查找 TreeNode<T>* IterativeTreeSearch(TreeNode<T>*node, T key); //插入元素 void TreeInsert(T key); //最大值 TreeNode<T>*TreeMax(TreeNode<T>*node); //最小值 TreeNode<T>*TreeMin(TreeNode<T>*node); //查找前驅結點 TreeNode<T>*TreePredecessor(T key); //查找後繼結點 TreeNode<T>*TreeSuccessor(T key); //用結點 nodeM 替換結點 nodeN,刪除操做的輔助函數 void TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN); //刪除結點是key的元素 void Delete(T key); private: TreeNode<T>* root; }; //中序遍歷 template<class T> void BStree<T>::Inorder(TreeNode<T>*node) { if (node == NULL) return; else { Inorder(node->lnode); cout << node->element << " "; Inorder(node->rnode); } } //遞歸查找,調用時,node的初始值是root template<class T> TreeNode<T>* BStree<T>::TreeSearch(TreeNode<T>*node, T key) { if ((node == NULL) || (key == node->element)) { if (node == NULL) cout << "不存在該元素" << endl; else cout << "存在該元素" << endl; return node; } if (key > node->element) return TreeSearch(node->rnode,key); else return TreeSearch(node->lnode,key); } //迭代查找,node參數爲root(根結點) template<class T> TreeNode<T>* BStree<T>::IterativeTreeSearch(TreeNode<T>*node, T key) { while (node != NULL&&key != node->element) { if (key < node->element) node = node->lnode; else node = node->rnode; } if (node == NULL) cout << "不存在該元素" << endl; else cout << "存在該元素" << endl; return node; } //插入元素 template<class T> void BStree<T>::TreeInsert(T key) { TreeNode<T>* y = NULL; TreeNode<T>* x = root; TreeNode<T>* z = new TreeNode<T>(key); //將須要插入的元素放入新創建的結點中 while (x != NULL) //找到要插入位置的雙親結點 { y = x; if (z->element < x->element) x = x->lnode; else x = x->rnode; } z->parent = y; if (y == NULL) // 判斷要插入的是:左 或 右結點 root = z; else if (z->element>y->element) y->rnode = z; else y->lnode = z; } //最大值,一直遍歷所給結點的右子樹 template<class T> TreeNode<T>*BStree<T>::TreeMax(TreeNode<T>*node) { while (node->rnode != NULL) node = node->rnode; cout << "最大值是:" << node->element << endl; return node; } // 最小值,一直遍歷所給結點的左子樹 template<class T> TreeNode<T>*BStree<T>::TreeMin(TreeNode<T>*node) { while (node->lnode != NULL) node = node->lnode; cout << "最小值是:" << node->element << endl; return node; } //查找後繼結點 template<class T> TreeNode<T>*BStree<T>::TreeSuccessor(T key) { TreeNode<T>* x = TreeSearch(root, key); //查找關鍵字key所對應的結點 if (x->rnode != NULL) //若是結點x存在右結點,則直接查找右結點爲跟的最小值 return TreeMin(x->rnode); /*若,不存在右結點 一、if(x==x->parent->lnode), 則 x 的後繼元素便是 x 的雙親結點 二、if(x==x->parent->rnode),則 x 的雙親 y 及 y->lnode均小於x, 直到 x 的某一祖先 Yn 爲左節點時,Yn 的雙親便是 x 的後繼元素 */ TreeNode<T>*y = x->parent; while (y != NULL&&x == y->rnode) { x = y; y = y->parent; } return y; } //查找前驅結點 template<class T> TreeNode<T>*BStree<T>::TreePredecessor(T key) { TreeNode<T>* x = TreeSearch(root, key); //查找關鍵字key所對應的結點 if (x->lnode != NULL) return TreeMax(x->lnode); //若x的左子樹不爲空,查找左子樹的最大值 TreeNode<T>*y = x->parent; while (y != NULL&&x == y->lnode) { x = y; y = y->lnode; } return y; } //用結點 m 替換結點 n,不包括v的左右子樹的更新 template<class T> void BStree<T>::TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN) { if (nodeN->parent == NULL) root = nodeM; else if (nodeN == nodeN->parent->lnode) // nodeN 是左結點,更新nodeN->parent 的左結點 nodeN->parent->lnode = nodeM; else nodeN->parent->rnode = nodeM; if (nodeM != NULL) nodeM->parent = nodeN->parent; } //刪除結點關節字是key的元素 template<class T> void BStree<T>::Delete(T key) { TreeNode<T>*z = IterativeTreeSearch(root,key); //z 是要刪除的結點 if (z->lnode == NULL) TransPlant(z->rnode,z); else if (z->rnode == NULL) TransPlant(z->lnode,z); else { //找要刪除結點的後繼元素, TreeNode<T>*y = TreeMin(z->rnode); //類的成員函數在調用成員函數(模板)時,直接寫函數名,不須要<T> if (y->parent != z) { TransPlant(y->rnode, y); //用 y 的右結點替代 y y->rnode = z->rnode; //y的右結點 = z的右結點 y->rnode->parent = y; } TransPlant(y,z); //用 y替代z y->lnode = z->lnode; y->lnode->parent = y; } }
測試代碼:注:生成的數組a[20]中,如有重複的數字,會有錯誤。spa
#include<iostream> #include"stdlib.h" #include<time.h> #include"BSTreecpp.cpp" using namespace std; int main() { //生成要插入的數據 int max = 500; int min = 0; srand((unsigned)time(NULL)); int a[20] = {}; int x = 0; for (int i = 0; i < 20; i++) { a[i] = rand() % (max - min) + min; cout << a[i] << " "; } cout << "輸入數據:" << endl; BStree<int>myTree; for (int i = 0; i < 20; i++) myTree.TreeInsert(a[i]); myTree.Inorder(myTree.Getroot()); cout << "二叉搜索樹中序遍歷:" << endl; //驗證遞歸查找 int b = 0; TreeNode<int>* A = myTree.TreeSearch(myTree.Getroot(), b); //驗證迭代查找 TreeNode<int>* B = myTree.IterativeTreeSearch(myTree.Getroot(), a[2]); //驗證求取最大值 TreeNode<int>* C = myTree.TreeMax(myTree.Getroot()); //驗證求取最小值 TreeNode<int>* D = myTree.TreeMin(myTree.Getroot()); //求取後繼結點 TreeNode<int>*E = myTree.TreeSuccessor(a[1]); cout << a[1] << " 的後繼元素是:" << E->element << endl; //求取前驅結點 TreeNode<int>*F = myTree.TreePredecessor(a[3]); cout << a[3] << " 的前驅元素是:" << F->element << endl; //驗證刪除結點 myTree.Delete(a[0]); myTree.Inorder(myTree.Getroot()); cout << "二叉搜索樹刪除元素後:" << endl; system("pause"); return 0; }