二叉平衡树

二叉平衡树又称为AVL树。它继承了二叉搜索树的规则,并加了一个规则。它的规则是:

1.每个结点的左子树和右子树的高度最多差1.

二叉平衡树由于不会产生像二叉搜索树那样的极端情况,所以查找,删除(懒惰删除)的时间复杂度为o(logn)。插入操作需要对树作出调整,所以时间复杂度略高于o(logn)。

如图所示,a-1为AVL树,而a-2则不是AVL树。

 

插入操作需要旋转树以维持高度差最多为1这一特点。

把必须重新平衡的节点叫作a。由于任意结点最多有两个儿子,因此高度不平衡时,a点的两棵子树的高度差2。将会出现以下四种不平衡的情况:

1.对a的左儿子的左子树进行一次插入。

2.对a的左儿子的右子树进行一次插入。

3.对a的右儿子的左子树进行一次插入。

4.对a的右儿子的右子树进行一次插入。

对于1、4两种情况可以通过单旋转达到平衡条件。对于2、3两种情况可以通过双旋转达到平衡条件。

 

单旋转LL:

单旋转RR:

 

 

双旋转LR:

双旋转RL:

 

具体实现:

  1 template<typename T>
  2 struct avl_tree_node
  3 {
  4     avl_tree_node(const T& _element, avl_tree_node *_left = NULL, avl_tree_node *_right = NULL, int h = 0, bool _isdeleted = false)
  5         : element(_element)
  6         , left(_left)
  7         , right(_right)
  8         , height(h)
  9         , isdeleted(_isdeleted)
 10     {
 11     }
 12     T    element;
 13     avl_tree_node    *left;
 14     avl_tree_node    *right;
 15     int    height;
 16     bool isdeleted;
 17 };
 18 
 19 template<typename T>
 20 class avl_tree
 21 {
 22     typedef avl_tree_node<T> tree_node;
 23 public:
 24     avl_tree() { m_root = NULL; }
 25     avl_tree(const avl_tree& rhs)
 26         : m_root(clone(rhs.m_root))
 27     {}
 28     const avl_tree& operator=(const avl_tree& rhs)
 29     {
 30         if(this!=&rhs)
 31         {
 32             clear();
 33             m_root = clone(rhs.m_root);
 34         }
 35     }
 36 
 37     ~avl_tree() 
 38     {
 39         clear(m_root);
 40     }
 41 
 42 public:
 43     // 最小值
 44     const T& min() const
 45     {
 46         tree_node* node = min(m_root);
 47         if(node)
 48         {
 49             return node->element;
 50         }
 51         throw std::runtime_error("查找二叉树无任何节点");
 52     }
 53 
 54     // 最大值
 55     const T& max() const
 56     {
 57         tree_node* node = max(m_root);
 58         if(node)
 59         {
 60             return node->element;
 61         }
 62         throw std::runtime_error("查找二叉树无任何节点");
 63     }
 64 
 65     // 判断树上是否包含该值
 66     bool contains(const T& x) const
 67     {
 68         return contains(x,m_root);
 69     }
 70 
 71     // 判断树是否为空
 72     bool is_empty() const
 73     {
 74         return m_root==NULL;
 75     }
 76 
 77     // 清空树
 78     void clear()
 79     {
 80         clear(m_root);
 81     }
 82 
 83     // 插入值为x的节点
 84     void insert(const T& x)
 85     {
 86         insert(x,m_root);
 87     }
 88 
 89     // 移除值为x的节点
 90     void remove(const T& x)
 91     {
 92         remove(x,m_root);
 93     }
 94 
 95     // 对所有节点执行某项动作
 96     template<typename Functor>
 97     void foreach(Functor& functor)
 98     {
 99         foreach(m_root,functor);
100     }
101 
102 private:
103     // 树最小节点
104     tree_node* min(tree_node* t) const
105     {
106         if( t==NULL )
107         {
108             return NULL;
109         }
110         while(t->left!=NULL)
111         {
112             t = t->left;
113         }
114         return t;
115     }
116 
117     // 树最大节点
118     tree_node* max(tree_node* t) const
119     {
120         if( t==NULL )
121         {
122             return NULL;
123         }
124         while(t->right!=NULL)
125         {
126             t = t->right;
127         }
128         return t;
129     }
130 
131     // 判断树是否存在该节点
132     bool contains(const T& x, tree_node* t) const
133     {
134         if( t == NULL )
135         {
136             return false;
137         }
138         else if( x<t->element )
139         {
140             return contains( x, t->left );
141         }
142         else if( x>t->element )
143         {
144             return contains(x, t->right);
145         }
146         else
147         {
148             if(!t->isdeleted)
149             {
150                 return true;
151             }
152             else
153             {
154                 return false;
155             }
156         }
157     }
158 
159     // 插入节点
160     void insert(const T& x, tree_node*& t)
161     {
162         if( t == NULL )
163         {
164             t = new tree_node(x,NULL,NULL);
165         }
166         else if( x<t->element)
167         {
168             insert(x,t->left);
169             if(height(t->left) - height(t->right) == 2)
170             {
171                 if( x<t->left->element)
172                 {
173                     rotate_single_left(t);
174                 }
175                 else
176                 {
177                     rotate_double_left(t);
178                 }
179             }
180         }
181         else if( x>t->element )
182         {
183             insert(x,t->right);
184             if(height(t->right) - height(t->left) == 2)
185             {
186                 if( x>t->right->element )
187                 {
188                     rotate_single_right(t);
189                 }
190                 else
191                 {
192                     rotate_double_right(t);
193                 }
194             }
195         }
196         else
197         {
198             if(t->isdeleted)
199             {
200                 t->isdeleted = false;
201             }
202         }
203         t->height = max(height(t->left),height(t->right)) + 1;
204     }
205 
206     // 移除某节点
207     void remove(const T& x, tree_node*& t)
208     {
209         if( t== NULL )
210         {
211             return;
212         }
213         else if( x < t->element)
214         {
215             remove(x,t->left);
216         }
217         else if( x > t->element )
218         {
219             remove(x,t->right);
220         }
221         else if( t->left != NULL && t->right != NULL)
222         {
223             //t->element = min( t->right )->element;
224             //remove( t->element, t->right);
225             t->isdeleted = true;
226         }
227         else
228         {
229             //avl_tree_node *old_node = t;
230             //t = (t->left != NULL)?t->left:t->right;
231             //delete old_node;
232             t->isdeleted = true;
233         }
234     }
235 
236     // 清除该节点为根节点的树
237     void clear(tree_node*& t)
238     {
239         if(t != NULL)
240         {
241             clear(t->left);
242             clear(t->right);
243             delete t;
244             t = NULL;
245         }
246     }
247 
248     // 对该节点的为根节点的树的所有子节点执行某项动作
249     template<typename Functor>
250     void foreach(tree_node* t, Functor& functor)
251     {
252         if(t!=NULL)
253         {
254             functor(t);
255             foreach(t->left, functor);
256             foreach(t->right, functor);
257         }
258     }
259 
260     // 深拷贝树
261     tree_node* clone(tree_node* t) const
262     {
263         if( t==NULL )
264         {
265             return NULL;
266         }
267         return new tree_node(t->element, clone(t->left), clone(t->right));
268     }
269 
270     // 单旋转-LL
271     void rotate_single_left(tree_node*& k2)
272     {
273         tree_node* k1 = k2->left;
274         k2->left = k1->right;
275         k1->right = k2;
276         k2->height = max(height(k2->left),height(k2->right)) + 1;
277         k1->height = max(height(k1->left),k2->height) + 1;
278         k2 = k1;
279     }
280 
281     // 单旋转-RR
282     void rotate_single_right(tree_node*& k2)
283     {
284         tree_node* k1 = k2->right;
285         k2->right = k1->left;
286         k1->left = k2;
287         k2->height = max(height(k2->left),height(k2->right)) + 1;
288         k1->height = max(height(k1->right),k2->height) + 1;
289         k2 = k1;
290     }
291 
292     // 双旋转-LR
293     void rotate_double_left(tree_node*& k3)
294     {
295         rotate_single_right(k3->left);
296         rotate_single_left(k3);    
297     }
298 
299     // 双旋转-RL
300     void rotate_double_right(tree_node*& k3)
301     {
302         rotate_single_left(k3->right);
303         rotate_single_right(k3);
304     }
305 
306     //
307     int height(tree_node*& node)
308     {
309         return node==NULL?-1:node->height;
310     }
311 
312 
313     int max(int m, int n)
314     {
315         return m>n?m:n;
316     }
317 
318 private:
319     tree_node    *m_root;
320 };

 

 

posted @ 2012-10-02 13:08  traits  阅读(1776)  评论(0编辑  收藏  举报