数据结构中用C++实现平衡二叉搜索树
2014-10-29 21:57
169 查看
#ifndef _AVL_H_ #define _AVL_H_ #include <iostream> #define LH 1 //左高 #define EH 0 //等高 #define RH -1 //右高 //平衡二叉排序树结点结构 template <class ElemType,class KeyType> struct AVLNode{ ElemType data; //结点数据域 AVLNode<ElemType,KeyType> *lchild; //结点左孩子 AVLNode<ElemType,KeyType> *rchild; //结点右孩子 int bf; //结点平衡因子 }; //平衡二叉排序树类 template< class ElemType,class KeyType> class AVL{ public: AVL (); ~AVL ( ); bool Insert(const ElemType & e,const KeyType & key);//平衡二叉排序树中插入关键字为key的元素e bool Delete(const KeyType & key);//平衡二叉排序树中删除关键字为key的元素 bool Search(const KeyType & key);//平衡二叉排序树中查找是否存在关键字为key的元素 int GetDepth(); //求平衡二叉排序树的深度 void InorderTraverse(); //中序遍历平衡二叉排序树 private: AVLNode<ElemType,KeyType> * m_T;//平衡二叉排序树根指针 void _Destroy(AVLNode<ElemType,KeyType> * &T);//销毁平衡二叉排序树 void _RRotate(AVLNode<ElemType,KeyType> * &T);//右旋操作 void _LRotate(AVLNode<ElemType,KeyType> * &T);//左旋操作 void _LeftBalance(AVLNode<ElemType,KeyType> * &T);//左平衡处理 void _RightBalance(AVLNode<ElemType,KeyType> * &T); //右平衡处理 bool _Insert(AVLNode<ElemType,KeyType> * &T,ElemType e,KeyType key,bool &bTaller);//平衡二叉排序树中插入关键字为key的元素,并保持平衡状态 bool _Delete(AVLNode<ElemType,KeyType> * &T,KeyType key,bool &bShorter);//平衡二叉排序树中删除关键字为Key的元素,并保持平衡状态 AVLNode<ElemType,KeyType>* _Search(AVLNode<ElemType,KeyType>* T,KeyType key);//平衡二叉排序树中查找是否存在关键字key int _GetDepth(AVLNode<ElemType,KeyType>* T);//求平衡二叉排序树的深度 void _InorderTraverse(AVLNode<ElemType,KeyType>* T);//中序遍历二叉树 }; template< class ElemType,class KeyType> AVL<ElemType,KeyType>::AVL () { m_T = NULL; } template< class ElemType,class KeyType> AVL<ElemType,KeyType>::~AVL ( ) { _Destroy(m_T); } template< class ElemType,class KeyType> bool AVL<ElemType,KeyType>::Insert(const ElemType & e,const KeyType & key) { bool bTaller; return _Insert(m_T, e, key,bTaller); } template< class ElemType,class KeyType> bool AVL<ElemType,KeyType>::Delete(const KeyType & key) { bool bShorter; return _Delete(m_T, key, bShorter); } //在平衡二叉排序树中查找关键字为key的元素是否存在 template< class ElemType,class KeyType> bool AVL<ElemType,KeyType>::Search(const KeyType & key) { if (_Search(m_T,key) != NULL) return true; else return false; } // 初始条件: 平衡二叉排序树T存在。操作结果: 返回T的深度 template <class ElemType,class KeyType> int AVL<ElemType,KeyType>::GetDepth() { return _GetDepth(m_T); } // 中序遍历二叉树 template <class ElemType,class KeyType> void AVL <ElemType,KeyType>::InorderTraverse() { _InorderTraverse(m_T); } //销毁平衡二叉排序树 template< class ElemType,class KeyType> void AVL<ElemType,KeyType>::_Destroy(AVLNode<ElemType,KeyType> * &T) { if(T){ _Destroy(T->lchild); _Destroy(T->rchild); delete T; } T=NULL; } //对以T为根的二叉排序树作右旋操作,操作后T指向新的树根结点 template< class ElemType,class KeyType> void AVL<ElemType,KeyType>::_RRotate(AVLNode<ElemType,KeyType> * &T) { AVLNode<ElemType,KeyType> * TempAVL; TempAVL = T->lchild; //TempAVL指向T的左子树的根结点 T->lchild = TempAVL->rchild; //TempAVL的右子树挂接作为T的左子树 TempAVL->rchild = T; T = TempAVL; //T指向新的树根结点 } //对以T为根的二叉排序树作左旋操作。操作后T指向新的树根结点 template< class ElemType,class KeyType> void AVL<ElemType,KeyType>::_LRotate(AVLNode<ElemType,KeyType> * &T) { AVLNode<ElemType,KeyType> * TempAVL; TempAVL = T->rchild; //TempAVL指向T的右子树的根结点 T->rchild = TempAVL->lchild; //TempAVL的左子树挂接作为T的右子树 TempAVL->lchild = T; T = TempAVL; //T指向新的树根结点 } //对以T为根结点的二叉排序树作左平衡处理,处理完毕后T指向新的树根结点 template< class ElemType,class KeyType> void AVL<ElemType,KeyType>::_LeftBalance(AVLNode<ElemType,KeyType> * &T) { AVLNode<ElemType,KeyType> * tr, * TempAVL; tr = T->lchild; //tr指向T的左子树的根结点 switch(tr->bf){ //根据tr的平衡因子,作相应调整 case LH: //新结点插在T的左孩子的左子树上,作右旋操作 T->bf = EH; _RRotate(T); tr->bf = EH; return; case RH: //新结点插在T的左孩子的右子树上,作两次旋转操作 TempAVL = tr->rchild; //TempAVL指向tr的右子树的根结点上 switch(TempAVL->bf){ case LH: T->bf = RH; tr->bf = EH; break; case EH: T->bf = tr->bf = EH; break; case RH: T->bf = EH; tr->bf = LH; break; } TempAVL->bf = EH; _LRotate(T->lchild); //对T的左子树作左旋操作 _RRotate(T); //对T作右旋操作 return; } return; } //对以T为根结点的二叉排序树作右平衡处理,处理完毕后T指向新的树根结点 template< class ElemType,class KeyType> void AVL<ElemType,KeyType>::_RightBalance(AVLNode<ElemType,KeyType> * &T) { AVLNode<ElemType,KeyType> * tr, *TempAVL; tr = T->rchild; //tr指向T的右子树的根结点 switch(tr->bf){ //根据tr的平衡因子,作相应调整 case RH: //新结点插在T的右孩子的右子树上,作左旋操作 T->bf = tr->bf = EH; _LRotate(T); return ; case LH: //新结点插在T的右孩子的左子树上,作两次旋转操作 TempAVL = tr->lchild; //TempAVL指向tr的左子树的根结点上 switch(TempAVL->bf){ case RH: tr->bf = EH; T->bf = LH; break; case EH: T->bf = tr->bf = EH; break; case LH: tr->bf = RH; T->bf = EH; break; } TempAVL->bf = EH; _RRotate(T->rchild); //对T的右子树作右旋操作 _LRotate(T); //对T作左旋操作 return; } return ; } //若在平衡二叉排序树中不存在关键字为key的结点,则插入一个数据值为e的新结点,并返回true,否则返回false //若插入过程中导致平衡二叉排序树失衡,则作相应调整,使之保持平衡状态,布尔值bTaller反映T是否长高。 template< class ElemType,class KeyType> bool AVL<ElemType,KeyType>::_Insert(AVLNode<ElemType,KeyType> * &T,ElemType e,KeyType key,bool &bTaller) { if(!T){ //若T为空树,则插入新结点作为根,bTaller为true T = new AVLNode<ElemType,KeyType>; T->lchild = T->rchild = NULL; T->bf = EH; T->data = e; bTaller = true; return true; } if(T->data == key) //平衡二叉排序树中已存在和key相同关键字的结点,不再插入,返回false return false; if(T->data > key){ //在T的左子树中进行搜索 if(!_Insert(T->lchild,e,key,bTaller)) return false; if(bTaller){ //在T的左子树中插入新结点并使得左子树长高 switch(T->bf){ //根据T的平衡因子作相应处理 case LH: //原本左子树高,则作左平衡处理 _LeftBalance(T); bTaller = false; return true; case EH: //原本等高,无需作平衡处理,整棵树长高 bTaller = true; T->bf = LH; return true; case RH: //原本右子树高,无需作平衡处理,整棵树未长高 T->bf = EH; bTaller = false; return true; } } }else{ //在T的右子树中进行搜索 if(!_Insert(T->rchild,e,key,bTaller)) return false; if(bTaller){ //在T的右子树中插入新结点并使得右子树长高 switch(T->bf){ //根据T的平衡因子作相应处理 case LH: //原本左子树高,无需作平衡处理,整棵树未长高 T->bf = EH; bTaller = false; return true; case EH: //原本等高,无需作平衡处理,整棵树长高 T->bf = RH; bTaller = true; return true; case RH: //原本右子树高,则作右平衡处理 _R 4000 ightBalance(T); bTaller = false; return true; } } } return true; } //若在平衡二叉排序树中存在和key有相同关键字的结点,则删除,并返回true,否则返回false //若删除过程中导致平衡二叉排序树失衡,则作相应调整,使之保持平衡状态,布尔值bTaller反映T是否缩短。 template< class ElemType,class KeyType> bool AVL<ElemType,KeyType>::_Delete(AVLNode<ElemType,KeyType> * &T,KeyType key,bool &bShorter) { KeyType TempData; AVLNode<ElemType,KeyType> * tr; if(!T) //T为空树,无法删除,返回false return false; if(T->data == key){ //找到数据值为key的结点T if(T->lchild == NULL && T->rchild == NULL){ //若T为叶子结点,删除 delete T; T = NULL; bShorter = true; return true; } else if(T->lchild){ //若T无右子树 tr = T->lchild; //tr作为T的左子树的根结点 while(tr->rchild) //沿着tr的右子树分支一直找到最右端的结点 tr = tr->rchild; TempData = T->data; T->data = tr->data; tr->data = TempData; if(!_Delete(T->lchild,key,bShorter)) return false; if(bShorter){ //在T的左子树中删除结点 switch(T->bf){ //根据T的平衡因子作相应处理 case LH: //原本左子树高,则无需作平衡处理,树高缩短 T->bf = EH; bShorter = true; return true; case EH: //原本等高,则无需作平衡处理,树高未缩短 T->bf = RH; bShorter = false; return true; case RH: //原本右高 if(T->rchild->bf == EH) bShorter = false; else bShorter = true; _RightBalance(T); //作右平衡处理 return true; } } }else if(T->rchild){ //若T无左子树 tr = T->rchild; //tr作为T的右子树的根结点 while(tr->lchild) tr = tr->lchild; //沿着tr的左子树分支一直找到最左端的结点 TempData = T->data; T->data = tr->data; tr->data = TempData; if(!_Delete(T->rchild,key,bShorter)) return false; if(bShorter){ //在T的右子树中删除结点 switch(T->bf){ //根据T的平衡因子作相应处理 case RH: //原本右子树高,则无需作平衡处理,树高缩短 bShorter = true; T->bf = EH; return true; case EH: //原本等高,则无需作平衡处理,树高未缩短 bShorter = false; T->bf = LH; return true; case LH: //原本左高 if(T->lchild->bf == EH) bShorter = false; else bShorter = true; _LeftBalance(T); //作左平衡处理 return true; } } } }else if(T->data > key){ //在T的左子树中搜索,若找到则删除 if(!_Delete(T->lchild,key,bShorter)) return false; if(bShorter){ switch(T->bf){ case LH: T->bf = EH; bShorter = true; return true; case EH: T->bf = RH; bShorter = false; return true; case RH: if(T->rchild->bf == EH) bShorter = false; else bShorter = true; _RightBalance(T); return true; } } }else{ //在T的右子树中搜索,若找到则删除 if(!_Delete(T->rchild,key,bShorter)) return false; if(bShorter){ switch(T->bf){ case RH: bShorter = true; T->bf = EH; return true; case EH: bShorter = false; T->bf = LH; return true; case LH: if(T->lchild->bf == EH) bShorter = false; else bShorter = true; _LeftBalance(T); return true; } } } return true; } //在以T为根的平衡二叉排序树中查找关键字为key的结点,若找到则返回该结点指针,否则返回NULL template< class ElemType,class KeyType> AVLNode<ElemType,KeyType> * AVL<ElemType,KeyType>::_Search(AVLNode<ElemType,KeyType> * T,KeyType key) { if(!T) return NULL; if(T->data == key) return T; if(T->data > key ) return _Search(T->lchild,key); else return _Search(T->rchild,key); } //获取平衡二叉排序树的深度 template< class ElemType,class KeyType> int AVL<ElemType,KeyType>::_GetDepth(AVLNode<ElemType,KeyType>* T) { if(!T) return 0; switch(T->bf){ case LH: return (1 + _GetDepth(T->lchild)); case RH: return (1 + _GetDepth(T->rchild)); default: return (1 + _GetDepth(T->lchild)); } } //中序遍历二叉树 template <class ElemType,class KeyType> void AVL<ElemType,KeyType> ::_InorderTraverse(AVLNode<ElemType,KeyType>* T) { if(T){ _InorderTraverse(T->lchild); cout << T->data<<" "; _InorderTraverse(T->rchild); } } #endif
#include <iostream> #include <string> using namespace std; #include "avl.h" int main() { cout << "---此程序实现平衡二叉树操作---" << endl << endl; AVL<int,int> avl; int n,x,select; bool flag = 0; cout << "请输入要插入的元素个数:"; cin >> n; cout << "请依次输入待插入的元素:"; while(n--){ cin >> x; avl.Insert(x,x); } do{ cout << "请选择操作:1. 插入 2. 删除 3. 查找 4. 显示树的深度 5.中序遍历平衡二叉树 6.退出"<<endl; cin >> select; switch (select){ case 1: cout << "请输入待插入元素:"; cin >> x; if (!avl.Insert(x,x)) cout << " 结果:插入失败!"; else cout << " 结果:插入成功!"; break; case 2: cout << "请输入待删除元素:"; cin >> x; if (!avl.Delete(x)) cout <<" 结果:删除失败!"; else cout <<" 结果:删除成功!"; break; case 3: cout<<"请输入待查找元素:"; cin>>x; if (!avl.Search(x)) cout <<" 结果:查找失败!"; else cout <<" 结果:查找成功!"; break; case 4: cout << "这棵平衡二叉树深度为:"; cout << avl.GetDepth(); cout << endl << endl; break; case 5: cout<<endl<<"该二叉排序树中序遍历为:"; avl.InorderTraverse(); cout<<endl<<endl; break; case 6: flag = 1; break; default: flag = 1; break; } } while (flag == 0); return 0; }
相关文章推荐
- C++实现常见数据结构
- 数据结构:矩阵程序C++实现
- 数据结构各种算法实现C++
- 数据结构_图_邻接表做存储结构实现求无向图的连通分量_C++实现
- 数据结构_图_邻接多重表做存储结构遍历无向图_C++实现
- 如何用c++实现四叉数的数据结构(一)
- C++ 自平衡二叉搜索树的实现
- 数据结构_串_用链表做存储结构实现KMP算法_C++实现
- 数据结构_串_串的模式匹配_KMP算法_C++实现
- C++如何实现哈希数据结构——map Library
- 现代程序设计——C++与数据结构面向对象的方法与实现
- 数据结构各种算法实现(C++模板)
- 数据结构学习系列三-单向循环链表(c++实现且应用模板)
- 数据结构_树_二叉树的建立、遍历、复制与移除_二叉链表存储_C++实现
- 数据结构_队列_用链表动态建立释放节点实现队列各种操作_C++实现
- 数据结构 链表的lua实现 仿照C++中list 实现
- 数据结构学习系列二-链表的C++实现
- 数据结构_链表_稀疏多项式求值_C++实现
- 数据结构_树_赫夫曼树及赫夫曼编码_C++实现
- C++数据结构-堆栈实现