二叉排序树(Binary Sort Tree),又称二叉查找树。
1、若左子树不为空,则左子树上所有结点的值均小于他的根结构的值;
2、若右子树不为空,则右子树上所有结点的值均大于他的根结构的值;
3、他的左、右子树也分别为二叉排序树。
使用中序遍历时,二叉排序树的输出顺序是由小到大的有序数列。
二叉排序树类的: 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); /*若,不存在右结点 1、if(x==x->parent->lnode), 则 x 的后继元素即是 x 的双亲结点 2、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]中,若有重复的数字,会有错误。
#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; }