1 #include<iostream> 2 using namespace std; 3 4 5 6 //AVL树节点信息 7 template<class T> 8 class TreeNode 9 { 10 public: 11 TreeNode():lson(NULL),rson(NULL),freq(1),hgt(-1){} 12 T data;//值 13 int hgt;//高度 14 unsigned int freq;//频率 15 TreeNode* lson;//指向左儿子的地址 16 TreeNode* rson;//指向右儿子的地址 17 }; 18 //AVL树类的属性和方法声明 19 template<class T> 20 class AVLTree 21 { 22 private: 23 TreeNode<T>* root;//根节点 24 void insertpri(TreeNode<T>* &node,T x);//插入 25 TreeNode<T>* findpri(TreeNode<T>* node,T x);//查找 26 void insubtree(TreeNode<T>* node);//中序遍历 27 void pretree(TreeNode<T>* node);//先序遍历 28 void Deletepri(TreeNode<T>* &node,T x);//删除 29 int height(TreeNode<T>* node);//求树的高度 30 void SingRotateLeft(TreeNode<T>* &k2);//左左情况下的旋转 31 void SingRotateRight(TreeNode<T>* &k2);//右右情况下的旋转 32 void DoubleRotateLR(TreeNode<T>* &k3);//左右情况下的旋转 33 void DoubleRotateRL(TreeNode<T>* &k3);//右左情况下的旋转 34 int Max(int cmpa,int cmpb);//求最大值 35 36 public: 37 AVLTree():root(NULL){} 38 void get_root(TreeNode<T> *&r); 39 void insert(T x);//插入接口 40 TreeNode<T>* find(T x);//查找接口 41 void Delete(T x);//删除接口 42 void traversal();//遍历接口 43 44 }; 45 //计算节点的高度 46 template<class T> 47 int AVLTree<T>::height(TreeNode<T>* node) 48 { 49 if(node!=NULL) 50 return node->hgt; 51 return -1; 52 } 53 //返回根 54 template<class T> 55 void AVLTree<T>::get_root(TreeNode<T> *&r) 56 { 57 r=root; 58 } 59 //求最大值 60 template<class T> 61 int AVLTree<T>::Max(int cmpa,int cmpb) 62 { 63 return cmpa>cmpb?cmpa:cmpb; 64 } 65 //左左情况下的旋转 66 template<class T> 67 void AVLTree<T>::SingRotateLeft(TreeNode<T>* &k2) 68 { 69 TreeNode<T>* k1; 70 k1=k2->lson; 71 k2->lson=k1->rson; 72 k1->rson=k2; 73 74 k2->hgt=Max(height(k2->lson),height(k2->rson))+1; 75 k1->hgt=Max(height(k1->lson),k2->hgt)+1; 76 k2=k1; 77 } 78 //右右情况下的旋转 79 template<class T> 80 void AVLTree<T>::SingRotateRight(TreeNode<T>* &k2) 81 { 82 TreeNode<T>* k1; 83 k1=k2->rson; 84 k2->rson=k1->lson; 85 k1->lson=k2; 86 87 k2->hgt=Max(height(k2->lson),height(k2->rson))+1; 88 k1->hgt=Max(height(k1->rson),k2->hgt)+1; 89 k2=k1; 90 } 91 //左右情况的旋转 92 template<class T> 93 void AVLTree<T>::DoubleRotateLR(TreeNode<T>* &k3) 94 { 95 SingRotateRight(k3->lson); 96 SingRotateLeft(k3); 97 } 98 //右左情况的旋转 99 template<class T> 100 void AVLTree<T>::DoubleRotateRL(TreeNode<T>* &k3) 101 { 102 SingRotateLeft(k3->rson); 103 SingRotateRight(k3); 104 } 105 //插入 106 template<class T> 107 void AVLTree<T>::insertpri(TreeNode<T>* &node,T x) 108 { 109 if(node==NULL)//如果节点为空,就在此节点处加入x信息 110 { 111 node=new TreeNode<T>(); 112 node->data=x; 113 return; 114 } 115 if(node->data>x)//如果x小于节点的值,就继续在节点的左子树中插入x 116 { 117 insertpri(node->lson,x); 118 if(2==height(node->lson)-height(node->rson)) 119 if(x<node->lson->data) 120 SingRotateLeft(node); 121 else 122 DoubleRotateLR(node); 123 } 124 else if(node->data<x)//如果x大于节点的值,就继续在节点的右子树中插入x 125 { 126 insertpri(node->rson,x); 127 if(2==height(node->rson)-height(node->lson))//如果高度之差为2的话就失去了平衡,需要旋转 128 if(x>node->rson->data) 129 SingRotateRight(node); 130 else 131 DoubleRotateRL(node); 132 } 133 else ++(node->freq);//如果相等,就把频率加1 134 node->hgt=Max(height(node->lson),height(node->rson ))+1; 135 } 136 //插入接口 137 template<class T> 138 void AVLTree<T>::insert(T x) 139 { 140 insertpri(root,x); 141 } 142 //查找 143 template<class T> 144 TreeNode<T>* AVLTree<T>::findpri(TreeNode<T>* node,T x) 145 { 146 if(node==NULL)//如果节点为空说明没找到,返回NULL 147 { 148 return NULL; 149 } 150 if(node->data>x)//如果x小于节点的值,就继续在节点的左子树中查找x 151 { 152 return findpri(node->lson,x); 153 } 154 else if(node->data<x)//如果x大于节点的值,就继续在节点的左子树中查找x 155 { 156 return findpri(node->rson,x); 157 } 158 else return node;//如果相等,就找到了此节点 159 } 160 //查找接口 161 template<class T> 162 TreeNode<T>* AVLTree<T>::find(T x) 163 { 164 return findpri(root,x); 165 } 166 //删除 167 template<class T> 168 void AVLTree<T>::Deletepri(TreeNode<T>* &node,T x) 169 { 170 if(node==NULL) return ;//没有找到值是x的节点 171 if(x < node->data) 172 { 173 Deletepri(node->lson,x);//如果x小于节点的值,就继续在节点的左子树中删除x 174 if(2==height(node->rson)-height(node->lson)) 175 if(node->rson->lson!=NULL&&(height(node->rson->lson)>height(node->rson->rson)) )//右左的情况 176 DoubleRotateRL(node); 177 else //右右的情况 178 SingRotateRight(node); 179 } 180 181 else if(x > node->data) 182 { 183 Deletepri(node->rson,x);//如果x大于节点的值,就继续在节点的右子树中删除x 184 if(2==height(node->lson)-height(node->rson)) 185 if(node->lson->rson!=NULL&& (height(node->lson->rson)>height(node->lson->lson) )) //左右的情况 186 DoubleRotateLR(node); 187 else //左左的情况 188 SingRotateLeft(node); 189 } 190 191 else//如果相等,此节点就是要删除的节点 192 { 193 if(node->lson&&node->rson)//此节点有两个儿子 194 { 195 TreeNode<T>* temp=node->rson;//temp指向节点的右儿子 196 while(temp->lson!=NULL) temp=temp->lson;//找到右子树中值最小的节点 197 //把右子树中最小节点的值赋值给本节点 198 node->data=temp->data; 199 node->freq=temp->freq; 200 Deletepri(node->rson,temp->data);//删除右子树中最小值的节点 201 if(2==height(node->lson)-height(node->rson)) 202 { 203 if(node->lson->rson!=NULL&& (height(node->lson->rson)>height(node->lson->lson) )) 204 DoubleRotateLR(node); 205 else 206 SingRotateLeft(node); 207 } 208 } 209 else//此节点有1个或0个儿子 210 { 211 TreeNode<T>* temp=node; 212 if(node->lson==NULL)//有右儿子或者没有儿子 213 node=node->rson; 214 else if(node->rson==NULL)//有左儿子 215 node=node->lson; 216 delete(temp); 217 temp=NULL; 218 } 219 } 220 if(node==NULL) return;//当前节点0个儿子,删除后为NULL,直接退出,不用求hgt 221 node->hgt=Max(height(node->lson),height(node->rson))+1; 222 return; 223 } 224 //删除接口 225 template<class T> 226 void AVLTree<T>::Delete(T x) 227 { 228 Deletepri(root,x); 229 } 230 //先序遍历函数 231 template<class T> 232 void AVLTree<T>::pretree(TreeNode<T>* node) 233 { 234 if(node==NULL) return; 235 cout<<node->data<<" ";//输出根节点 236 pretree(node->lson);//先遍历左子树 237 pretree(node->rson);//再遍历右子树 238 } 239 //中序遍历函数 240 template<class T> 241 void AVLTree<T>::insubtree(TreeNode<T>* node) 242 { 243 if(node==NULL) return; 244 insubtree(node->lson);//先遍历左子树 245 cout<<node->data<<" ";//输出根节点 246 insubtree(node->rson);//再遍历右子树 247 } 248 //遍历接口 249 template<class T> 250 void AVLTree<T>::traversal() 251 { 252 253 pretree(root); 254 cout<<endl; 255 insubtree(root); 256 cout<<endl; 257 }