C++实践笔记(四)----AVL树的简单实现

    关于AVL树的分析,请见:数据结构与算法分析学习笔记(二)--AVL树的算法思路整理

    这里给出AVL树的结构定义以及insert,remove和print三种操作的例程:

 

  1 #include <iostream>
  2 #include <list>
  3 #include <utility>
  4 #include < string>
  5  using  namespace std;
  6 
  7  static  const  string PRINT_SPACES = "    ";
  8 
  9 template <typename Object>
 10  class AVLTree
 11 {
 12  public:
 13     AVLTree(){root=NULL;}
 14 
 15      void insert( const Object &x)
 16     {insert(x,root);}
 17      void remove( const Object &x)
 18     {remove(x,root);}
 19 
 20      void print();
 21 
 22  private:
 23      struct AVLnode
 24     {
 25         Object data;
 26         AVLnode *left;
 27         AVLnode *right;
 28          int height;
 29 
 30         AVLnode(Object ob,AVLnode *l,AVLnode *r, int h= 0):data(ob),left(l),right(r),height(h){}
 31     };
 32 
 33     AVLnode *root;
 34 
 35      void insert( const Object &x,AVLnode * &t);
 36 
 37      void remove( const Object &x,AVLnode *&t);
 38 
 39      void leftSingleRotation(AVLnode * &t);
 40      void rightSingleRotation(AVLnode * &t);
 41 
 42      void leftDoubleRotation(AVLnode * &t);
 43      void rightDoubleRotation(AVLnode * &t);
 44 
 45      int height(AVLnode * &t)
 46     {
 47          // 结点的高度,空结点的高度为-1
 48           return t==NULL?- 1:t->height;
 49     }
 50 
 51      int max( int a, int b)
 52     {
 53          return a<b?b:a;
 54     }
 55 
 56      int powerOf2( int x) // 求2的x次方(x大于等于0)
 57      {
 58          if(x== 0) return  1;
 59          int m= 1;
 60          while(--x>= 0)
 61             m*= 2;
 62          return m;    
 63     }
 64 
 65     AVLnode * max_node(AVLnode * t) // max和min使用递归的话不能使用引用形参,不能返回引用
 66      {
 67          if(!t)
 68              return NULL;
 69          if(t->right)
 70              return max_node(t->right);
 71          else
 72              return t;
 73     }
 74 
 75     AVLnode * min_node(AVLnode * t)
 76     {
 77          if(t) // 考虑一下t为空的情况,使其更全面,毕竟这个函数是可以加一个public版本的重载供用户使用
 78               while(t->left)
 79                 t=t->left;
 80          return t;
 81     }
 82 };
 83 
 84 template <typename Object>
 85  void AVLTree<Object>::insert( const Object &x,AVLnode * &t)
 86 {
 87      if(!t)
 88         t= new AVLnode(x,NULL,NULL);
 89      else  if(x<t->data)
 90     {
 91         insert(x,t->left);
 92          if(height(t->left)-height(t->right)== 2) // 在左子树插入结点后,不可能右子树比左子树高2
 93               if(x<t->left->data)
 94                 leftSingleRotation(t); // 左单旋转
 95               else
 96                 leftDoubleRotation(t); // 左双旋转
 97           else // 不需要调整就满足平衡条件的话,只需要重新计算其高度就好
 98              t->height=max(height(t->left),height(t->right))+ 1;
 99     }
100      else  if(x>t->data)
101     {
102         insert(x,t->right);
103          if(height(t->right)-height(t->left)== 2)
104              if(x>t->right->data)
105                 rightSingleRotation(t); // 右单旋转
106               else
107                 rightDoubleRotation(t); // 右双旋转
108           else
109             t->height=max(height(t->left),height(t->right))+ 1;
110     }
111      else; // 不考虑重复的值
112  }
113 
114 template <typename Object>
115  void AVLTree<Object>::leftSingleRotation(AVLnode * &t) // 左单旋转
116  {
117     AVLnode *s=t->left;
118     t->left=s->right;
119     s->right=t;
120     t->height=max(height(t->left),height(t->right))+ 1; // 重新计算s和t的高度
121      s->height=max(height(s->left),t->height)+ 1;
122     t=s;
123 }
124 
125 template <typename Object>
126  void AVLTree<Object>::rightSingleRotation(AVLnode * &t)
127 {
128     AVLnode *s=t->right;
129     t->right=s->left;
130     s->left=t;
131     t->height=max(height(t->left),height(t->right))+ 1;
132     s->height=max(t->height,height(s->right))+ 1;
133     t=s;
134 }
135 
136 template <typename Object>
137  void AVLTree<Object>::leftDoubleRotation(AVLnode * &t) // 左双旋转
138  {
139     AVLnode *p=t->left;
140     AVLnode *q=p->right;
141     t->left=q->right;
142     p->right=q->left;
143     q->left=p;
144     q->right=t;
145     t->height=max(height(t->left),height(t->right))+ 1; // 重新计算3个结点的高度
146      p->height=max(height(p->left),height(p->right))+ 1;
147     q->height=max(p->height,t->height)+ 1;
148     t=q;
149 }
150 
151 template <typename Object>
152  void AVLTree<Object>::rightDoubleRotation(AVLnode * &t)
153 {
154     AVLnode *p=t->right;
155     AVLnode *q=p->left;
156     t->right=q->left;
157     p->left=q->right;
158     q->right=p;
159     q->left=t;
160     t->height=max(height(t->left),height(t->right))+ 1;
161     p->height=max(height(p->left),height(p->right))+ 1;
162     q->height=max(t->height,p->height)+ 1;
163     t=q;
164 }
165 
166 template <typename Object>
167  void AVLTree<Object>::remove( const Object &x,AVLnode *&t)
168 {
169      if(!t) return; // 没有找到要删除的值,do nothing
170       if(x<t->data)
171     {
172         remove(x,t->left);
173          if(height(t->right)-height(t->left)== 2)
174         {
175              // 右子树比左子树高2,那么在删除操作之前右子树比左子树高1,
176               // 也就是说t的右子树必然不为空,甚至必然有非空子树(高度至少为1).
177              AVLnode *s=t->right;
178              if(height(s->left)>height(s->right))
179                 rightDoubleRotation(t); // 右双旋转
180               else
181                 rightSingleRotation(t); // 右单旋转
182          }
183          else
184              // 不需要调整就满足平衡条件的话,只需要重新计算其高度就好
185              t->height=max(height(t->left),height(t->right))+ 1;
186     }
187      else  if(x>t->data)
188     {
189         remove(x,t->right);
190          if(height(t->left)-height(t->right)== 2)
191         {
192             AVLnode *s=t->left;
193              if(height(s->right)>height(s->left))
194                 leftDoubleRotation(t); // 左双旋转
195               else
196                 leftSingleRotation(t); // 左单旋转
197          }
198          else
199             t->height=max(height(t->left),height(t->right))+ 1;
200     }
201      else
202     {
203          if(t->left&&t->right)
204          // t的左右子树都非空,把remove操作转移到只有一个非空子树的结点或者叶子结点上去
205          {
206              if(height(t->left)>height(t->right))
207              // 把remove操作往更高的那颗子树上转移
208              {
209                  // 左子树中的最大值
210                  t->data=max_node(t->left)->data;
211                 remove(t->data,t->left);
212             }
213              else
214             {
215                  // 右子树中的最小值
216                  t->data=min_node(t->right)->data;
217                 remove(t->data,t->right);
218             }
219         }
220          else
221         {
222             AVLnode *oldnode=t;
223             t=t->left?t->left:t->right;
224             delete oldnode;
225         }
226     }
227 }
228 
229  // 使用队列层次遍历打印树
230  template <typename Object>
231  void AVLTree<Object>::print()
232 {
233      if(!root) return;
234     list<pair<AVLnode *, int> > lis; // int是标志位,0表示正常值,-1表示此处没有值,应打印空格
235      lis.push_back(make_pair(root, 0));
236     AVLnode *em= new AVLnode( 0,NULL,NULL); // 一个空的点
237       int count= 1,j= 0; // count表示当前行的最大结点数,j表示当前行已打印的结点数(空结点也计数)
238       int hg=root->height; // 当前行的高度,计算空格时使用
239 
240      while(hg>= 0) // 当hg<0时说明最后一行(树叶)已经打印完毕
241      {
242          while(j++!=count)
243         {
244              for( int i= 1;i<powerOf2(hg);i++)
245                 cout<<PRINT_SPACES; // 打印前一部分空格
246               if(lis.front().second== 0)
247                 cout<<lis.front().first->data;
248              else
249                 cout<<PRINT_SPACES; // int位为-1,则打印空格以对齐
250               if(lis.front().first->left) // 左子树入队
251                  lis.push_back(make_pair(lis.front().first->left, 0));
252              else
253                 lis.push_back(make_pair(em,- 1));
254              if(lis.front().first->right) // 右子树入队
255                  lis.push_back(make_pair(lis.front().first->right, 0));
256              else
257                 lis.push_back(make_pair(em,- 1));
258              for( int i= 0;i<powerOf2(hg);i++)
259                 cout<<PRINT_SPACES; // 打印后一部分空格
260              lis.pop_front();
261         }
262         j= 0;
263         count*= 2; // 下一行的最大节点数是上一行的两倍
264          --hg; // 高度减1
265          cout<<endl;     // 换行
266      }
267     delete em;
268     lis.clear();
269 }

 

你可能感兴趣的:(C++实践笔记(四)----AVL树的简单实现)