zoukankan      html  css  js  c++  java
  • 二叉平衡树

      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 }
  • 相关阅读:
    《图像处理实例》 之 Voronoi 图
    《图像处理实例》 之 Voronoi 图
    《图像处理实例》 之 Voronoi 图
    Docker 1.13.0 详细更新日志
    Docker 1.13.0 详细更新日志
    Docker 1.13.0 详细更新日志
    Docker 1.13.0 详细更新日志
    Ubuntu上安装VMware tools
    Ubuntu上安装VMware tools
    Casper CBC 简要说明
  • 原文地址:https://www.cnblogs.com/ljwTiey/p/4320868.html
Copyright © 2011-2022 走看看