BST, AVL Tree 和 Splay Tree 的实现

Posted lyf520

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BST, AVL Tree 和 Splay Tree 的实现相关的知识,希望对你有一定的参考价值。

一、定义。

1.1 BST

  二叉搜索树,也称有序二叉树,排序二叉树,是指一棵空树或者具有下列性质的二叉树:

  ① 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

  ② 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

  ③ 任意节点的左、右子树也分别为二叉查找树。

  ④ 没有键值相等的节点。

1.2 AVL Tree

  平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

  平衡因子(bf):结点的左子树的深度减去右子树的深度。

  保持平衡是依赖于旋转操作,分为LL, RR, LR, RL四种情况。

  LL单旋即右旋。

  技术分享图片

技术分享图片

技术分享图片

技术分享图片

1.3 Splay Tree

  伸展树的出发点是这样的:考虑到局部性原理(刚被访问的内容下次可能仍会被访问,查找次数多的内容可能下一次会被访问),为了使整个查找时间更小,被查频率高的那些节点应当经常处于靠近树根的位置。这样,很容易得想到以下这个方案:每次查找节点之后对树进行重构,把被查找的节点搬移到树根,这种自调整形式的二叉查找树就是伸展树。每次对伸展树进行操作后,它均会通过旋转的方法把被访问节点旋转到树根的位置。

  为了将当前被访问节点旋转到树根,我们通常将节点自底向上旋转,直至该节点成为树根为止。“旋转”的巧妙之处就是在不打乱数列中数据大小关系(指中序遍历结果是全序的)情况下,所有基本操作的平摊复杂度仍为O(log n)。

  伸展树主要有三种旋转操作,分别为单旋转,一字形旋转和之字形旋转。为了便于解释,我们假设当前被访问节点为X,X的父亲节点为Y(如果X的父亲节点存在),X的祖父节点为Z(如果X的祖父节点存在)。这里的单旋与之字形旋转与AVL树是一致的,因此这里只列出Zig-Zig。

  技术分享图片

 

  Splay操作可以自底向上也可以自顶向下,我只实现了自底向上的算法,自顶向下以后有机会再补充,因为每次操作都需要把操作的结点翻转到根,所以用Zig-Zig代替单旋,每次上升两层,如果根节点恰好是父节点,则此时只需要一次单旋。

 

二、复杂度分析。

  AVL无论是在顺序逆序或者随机插入删除的情况下效果都不错,而Splay在按照顺序或者逆序的情况下效果比较好,因为预测准确,而随机则无法预测,所做的Splay操作都是多余的,所以比较慢,AVL 和 Splay 哪个更合适需要具体情况具体分析。

2.1 BST

Algorithm   Average Worst case
Space   O(n) O(n)
Search   O(log n) O(n)
Insert   O(log n) O(n)
Delete   O(log n) O(n)

2.2 AVL Tree

Algorithm   Average Worst case
Space   O(n) O(n)
Search   O(log n)
O(log n)
Insert   O(log n)
O(log n)
Delete   O(log n)
O(log n)

2.3 Splay Tree

Algorithm   Average Worst case
Space   O(n) O(n)
Search   O(log n) amortized O(log n)
Insert   O(log n) amortized O(log n)
Delete   O(log n) amortized O(log n)

 

三、实现。

  水平有限,写的比较啰嗦,见谅。

  1 #include <iostream>
  2 using namespace std;
  3 // Binery Search Tree Node
  4 class BSTreeNode {
  5 public:
  6     int data;
  7     BSTreeNode* leftChild;
  8     BSTreeNode* rightChild;
  9     BSTreeNode(int value): data(value), leftChild(NULL), rightChild(NULL){}
 10 };
 11 // AVL Tree Node
 12 class AVLTreeNode {
 13 public:
 14     int data;
 15     // The height of node
 16     int height;
 17     AVLTreeNode* leftChild;
 18     AVLTreeNode* rightChild;
 19     AVLTreeNode(int value): data(value), height(0), leftChild(NULL), rightChild(NULL){}
 20 };
 21 // Splay Tree Node
 22 class SplayTreeNode {
 23 public:
 24     int data;
 25     // The pointer to parent
 26     SplayTreeNode* parent;
 27     SplayTreeNode* leftChild;
 28     SplayTreeNode* rightChild;
 29     SplayTreeNode(int value): data(value), parent(NULL), leftChild(NULL), rightChild(NULL){}
 30 };
 31 // Preorder traversal
 32 void previsit(SplayTreeNode* T){
 33     if(T){
 34         cout<<T->data<< ;
 35         previsit(T->leftChild);
 36         previsit(T->rightChild);
 37     }
 38 
 39 }
 40 // Preorder traversal
 41 void previsit(BSTreeNode* T){
 42     if(T!=NULL){
 43         cout<<T->data<< ;
 44         previsit(T->leftChild);
 45         previsit(T->rightChild);
 46     }
 47 }
 48 // Preorder traversal
 49 void previsit(AVLTreeNode* T){
 50     if(T){
 51             cout<<T->data<< ;
 52             previsit(T->leftChild);
 53             previsit(T->rightChild);
 54     }
 55 
 56 }
 57 // Find the minimun element
 58 BSTreeNode* BSTreeFindMin(BSTreeNode* T) {
 59     if (T == NULL) {
 60         return NULL;
 61     } else if (T->leftChild == NULL) {
 62         return T;
 63     } else {
 64         return BSTreeFindMin(T->leftChild);
 65     }
 66 }
 67 // Insert operation of Binery Search Tree
 68 BSTreeNode* BSTreeInsert(int value, BSTreeNode* T) {
 69     if (T == NULL) {
 70         T = new BSTreeNode(value);
 71     } else {
 72         // If value is smaller than element
 73         if (value < T->data) {
 74             T->leftChild = BSTreeInsert(value, T->leftChild);
 75         } 
 76         // If value is larger than element
 77         else if (value > T->data) {
 78             T->rightChild = BSTreeInsert(value, T->rightChild);
 79         }
 80     }
 81     return T;
 82 }
 83 // Delete operation of Binery Search Tree
 84 BSTreeNode* BSTreeDelete(int value, BSTreeNode* T) {
 85     if (T == NULL) {
 86         return NULL;
 87     } 
 88     // If value is smaller than element
 89     else if (value < T->data) {
 90         T->leftChild = BSTreeDelete(value, T->leftChild);
 91     } 
 92     // If value is larger than element
 93     else if (value > T->data) {
 94         T->rightChild = BSTreeDelete(value, T->rightChild);
 95     } 
 96     // If value is equal to element
 97     else {
 98         if (T->leftChild && T->rightChild) {
 99             // Two children
100             BSTreeNode* tmp = BSTreeFindMin(T->rightChild);
101             T->data = tmp->data;
102             //delete tmp;
103             T->rightChild = BSTreeDelete(T->data, T->rightChild);
104         } else {
105             // One or no child
106             if (T->leftChild) {
107                 T = T->leftChild;
108             } else if (T->rightChild) {
109                 T = T->rightChild;
110             } else {
111                 T = NULL;
112             }
113         }
114     }
115     return T;
116 }
117 // Get the height of AVL Tree
118 int getHeight(AVLTreeNode* T) {
119     if (T == NULL) {
120         return -1;
121     } else {
122         return T->height;
123     }
124 }
125 // Get the larger one element
126 int Max(int x, int y) {
127     return (x > y) ? x : y;
128 }
129 // LL Rotation
130 AVLTreeNode* SingleRotateWithLeft(AVLTreeNode* K2) {
131     AVLTreeNode* K1;
132 
133     K1 = K2->leftChild;
134     K2->leftChild = K1->rightChild;
135     K1->rightChild = K2;
136 
137     // Update the height of node
138     K2->height = Max(getHeight(K2->leftChild), getHeight(K2->rightChild)) + 1;
139     K1->height = Max(getHeight(K1->leftChild), getHeight(K1->rightChild)) + 1;
140     return K1;
141 }
142 // RR Rotation
143 AVLTreeNode* SingleRotateWithRight(AVLTreeNode* K2) {
144     AVLTreeNode* K1;
145 
146     K1 = K2->rightChild;
147     K2->rightChild = K1->leftChild;
148     K1->leftChild = K2;
149 
150     // Update the height of node
151     K2->height = Max(getHeight(K2->leftChild), getHeight(K2->rightChild)) + 1;
152     K1->height = Max(getHeight(K1->leftChild), getHeight(K1->rightChild)) + 1;
153     return K1;
154 }
155 // LR Rotation
156 AVLTreeNode* DoubleRotateWithLeft(AVLTreeNode* K3) {
157     K3->leftChild = SingleRotateWithRight(K3->leftChild);
158     return SingleRotateWithLeft(K3);
159 }
160 // RL Rotation
161 AVLTreeNode* DoubleRotateWithRight(AVLTreeNode* K3) {
162     K3->rightChild = SingleRotateWithLeft(K3->rightChild);
163     return SingleRotateWithRight(K3);
164 }
165 // Find the minimum element
166 AVLTreeNode* AVLTreeFindMin(AVLTreeNode* T) {
167     if (T == NULL) {
168         return NULL;
169     } else if (T->leftChild == NULL) {
170         return T;
171     } else {
172         return AVLTreeFindMin(T->leftChild);
173     }
174 }
175 // Insert operation of AVL Tree
176 AVLTreeNode* AVLTreeInsert(int value, AVLTreeNode* T) {
177     if (T == NULL) {
178         T = new AVLTreeNode(value);
179         return T;
180     } else {
181         // If value is smaller than element
182         if (value < T->data) {
183             T->leftChild = AVLTreeInsert(value, T->leftChild);
184             // If the balance is broken
185             if (getHeight(T->leftChild) - getHeight(T->rightChild) == 2) {
186                 if (value < T->leftChild->data) {
187                     // LL Rotation
188                     T = SingleRotateWithLeft(T);
189                 } else {
190                     // LR Rotation
191                     T = DoubleRotateWithLeft(T);
192                 }
193             }
194         } 
195         // If value is larger than element
196         else if (value > T->data) {
197             T->rightChild = AVLTreeInsert(value, T->rightChild);
198             // If the balance is broken
199             if (getHeight(T->rightChild) - getHeight(T->leftChild) == 2) {
200                 if (value > T->rightChild->data) {
201                     // RR Rotation
202                     T = SingleRotateWithRight(T);
203                 } else {
204                     // RL Rotation
205                     T = DoubleRotateWithRight(T);
206                 }
207             }
208         }
209 
210         // Update the height of node
211         if (T) {
212             T->height = Max(getHeight(T->leftChild), getHeight(T->rightChild)) + 1;
213         }
214         return T;
215     }
216 }
217 // Delete operation of AVL Tree
218 AVLTreeNode* AVLTreeDelete(int value, AVLTreeNode* T) {
219     if (T == NULL) {
220         return NULL;
221     } else {
222         // If value is smaller than element
223         if (value < T->data) {
224             T->leftChild = AVLTreeDelete(value, T->leftChild);
225             // If the balance is broken
226             if (getHeight(T->rightChild) - getHeight(T->leftChild) == 2) {
227                 // Delete is similar to insert
228                 // We can assume the unbalance is caused by insert an element
229                 if (getHeight(T->rightChild->rightChild) >= getHeight(T->rightChild->leftChild)) {
230                     // RR Rotation
231                     T = SingleRotateWithRight(T);
232                 } else {
233                     // RL Rotation
234                     T = DoubleRotateWithRight(T);
235                 }
236             }
237         } 
238         // If value is larger than element
239         else if (value > T->data) {
240             T->rightChild = AVLTreeDelete(value, T->rightChild);
241             // If the balance is broken
242             if (getHeight(T->leftChild) - getHeight(T->rightChild) == 2) {
243                 // Delete is similar to insert
244                 // We can assume the unbalance is caused by insert an element
245                 if (getHeight(T->leftChild->leftChild) >= getHeight(T->leftChild->rightChild)) {
246                     // LL Rotation
247                     T = SingleRotateWithLeft(T);
248                 } else {
249                     // LR Rotation
250                     T = DoubleRotateWithLeft(T);
251                 }
252             }
253         } 
254         // If value is equal to element
255         else {
256             if (T->leftChild && T->rightChild) {
257                 // Two children
258                 AVLTreeNode* tmp = AVLTreeFindMin(T->rightChild);
259                 T->data = tmp->data;
260                 //delete tmp;
261                 T->rightChild = AVLTreeDelete(T->data, T->rightChild);
262             } else {
263                 // One or no child
264                 if (T->leftChild) {
265                     T = T->leftChild;
266                 } else if (T->rightChild) {
267                     T = T->rightChild;
268                 } else {
269                     T = NULL;
270                 }
271             }
272         }
273     }
274 
275     // Update the height of node
276     if (T) {
277         T->height = Max(getHeight(T->leftChild), getHeight(T->rightChild)) + 1;
278     }
279     return T;
280 }
281 // LL Rotation of Splay Tree
282 SplayTreeNode* SplaySingleRotateWithLeft(SplayTreeNode* K2) {
283     // It is similar to AVL Tree
284     // But we must update the parent of node
285     SplayTreeNode* K1 = K2->leftChild;
286     SplayTreeNode* P = K2->parent;
287     K2->leftChild = K1->rightChild;
288     if(K2->leftChild){
289         K2->leftChild->parent = K2;
290     }
291     K1->rightChild = K2;
292     K1->rightChild->parent = K1;
293     K1->parent = P;
294     if (P != NULL) {
295         if (P->leftChild == K2) {
296             P->leftChild = K1;
297         } else {
298             P->rightChild = K1;
299         }
300     }
301     return K1;
302 }
303 // RR Rotation of Splay Tree
304 SplayTreeNode* SplaySingleRotateWithRight(SplayTreeNode* K2) {
305     // It is similar to AVL Tree
306     // But we must update the parent of node
307     SplayTreeNode* K1 = K2->rightChild;
308     SplayTreeNode* P = K2->parent;
309     K2->rightChild = K1->leftChild;
310     if(K2->rightChild){
311         K2->rightChild->parent = K2;    
312     }
313     K1->leftChild = K2;
314     if(K1->leftChild){
315         K1->leftChild->parent = K1;
316     }
317     
318     K1->parent = P;
319     if (P != NULL) {
320         if (P->leftChild == K2) {
321             P->leftChild = K1;
322         } else {
323             P->rightChild = K1;
324         }
325     }
326     return K1;
327 }
328 // LR Rotation
329 SplayTreeNode* SplayDoubleRotateWithLeft(SplayTreeNode* K3) {
330     K3->leftChild = SplaySingleRotateWithRight(K3->leftChild);
331     return SplaySingleRotateWithLeft(K3);
332 }
333 // RL Rotation
334 SplayTreeNode* SplayDoubleRotateWithRight(SplayTreeNode* K3) {
335     K3->rightChild = SplaySingleRotateWithLeft(K3->rightChild);
336     return SplaySingleRotateWithRight(K3);
337 }
338 // L-Zig-Zig
339 SplayTreeNode* ZigZigWithLeft(SplayTreeNode* K3) {
340     SplayTreeNode* parent = K3->parent;
341     SplayTreeNode* K2 = K3->leftChild;
342     SplayTreeNode* K1 = K2->leftChild;
343 
344     K3->leftChild = K2->rightChild;
345     if (K2->rightChild != NULL) {
346         K3->leftChild->parent = K3;
347     }
348     K2->rightChild = K3;
349     K2->rightChild->parent = K2;
350     K2->leftChild = K1->rightChild;
351     if (K1->rightChild != NULL) {
352         K2->leftChild->parent = K2;
353     }
354     K1->rightChild = K2;
355     K1->rightChild->parent = K1;
356     K1->parent = parent;
357     if (parent != NULL) {
358         if (parent->leftChild == K3) {
359             parent->leftChild = K1;
360         } else {
361             parent->rightChild = K1;
362         }
363     }
364     return K1;
365 }
366 // R-Zig-Zig
367 SplayTreeNode* ZigZigWithRight(SplayTreeNode* K3) {
368     SplayTreeNode* parent = K3->parent;
369     SplayTreeNode* K2 = K3->leftChild;
370     SplayTreeNode* K1 = K2->leftChild;
371 
372     K3->rightChild = K2->leftChild;
373     if (K2->leftChild != NULL) {
374         K3->rightChild->parent = K3;
375     }
376     K2->leftChild = K3;
377     K2->leftChild->parent = K2;
378     K2->rightChild = K1->leftChild;
379     if (K1->leftChild != NULL) {
380         K2->rightChild->parent = K2;
381     }
382     K1->leftChild = K2;
383     K1->leftChild->parent = K1;
384     K1->parent = parent;
385     if (parent != NULL) {
386         if (parent->leftChild == K3) {
387             parent->leftChild = K1;
388         } else {
389             parent->rightChild = K1;
390         }
391     }
392     return K1;
393 }
394 // Insert operation of Splay Tree without Splay
395 // It is similar to insert operation of Binery Search Tree
396 SplayTreeNode* PreInsert(int value, SplayTreeNode* T) {
397     if (T == NULL) {
398         T = new SplayTreeNode(value);
399     } else {
400         if (value < T->data) {
401             T->leftChild = PreInsert(value, T->leftChild);
402             // Update the parent of node
403             T->leftChild->parent = T;
404         } else if (value > T->data) {
405             T->rightChild = PreInsert(value, T->rightChild);
406             // Update the parent of node
407             T->rightChild->parent = T;
408         }
409     }
410     return T;
411 }
412 // Find the maximum element
413 SplayTreeNode* SplayTreeFindMax(SplayTreeNode* T) {
414     if (T == NULL) {
415         return NULL;
416     } else if (T->rightChild == NULL) {
417         return T;
418     } else {
419         return SplayTreeFindMax(T->rightChild);
420     }
421 }
422 // Find the minimum element
423 SplayTreeNode* SplayTreeFindMin(SplayTreeNode* T) {
424     if (T == NULL) {
425         return NULL;
426     } else if (T->leftChild == NULL) {
427         return T;
428     } else {
429         return SplayTreeFindMin(T->leftChild);
430     }
431 }
432 // Find the element and return the node
433 SplayTreeNode* Find(int value, SplayTreeNode* T) {
434     if (T == NULL) {
435         return NULL;
436     } else if (T->data == value) {
437         return T;
438     } else if (T->data > value) {
439         return Find(value, T->leftChild);
440     } else {
441         return Find(value, T->rightChild);
442     }
443 }
444 // Splay operation of Splay Tree
445 SplayTreeNode* Splay(int value, SplayTreeNode* T) {
446     SplayTreeNode* K = Find(value, T);
447     // Parent node
448     SplayTreeNode* P = NULL;
449     // Grandparent node
450     SplayTreeNode* GP = NULL;
451     // If node doesn‘t exist
452     if (K == NULL) {
453         return T;
454     }
455     // Do rotation until K arrives at root or is the child of root
456     while (T->leftChild != K && T->rightChild != K) {
457         P = K->parent;
458         // Break the loop if just need single rotation
459         if(P==NULL||P->parent==NULL){
460             break;
461         }
462         GP = P->parent;
463         if (GP->leftChild == P && P->leftChild == K) {
464             // L-Zig-Zig
465             ZigZigWithLeft(GP);
466         } else if (GP->leftChild == P && P->rightChild == K) {
467             // LR Rotation
468             SplayDoubleRotateWithLeft(GP);
469         } else if (GP->rightChild == P && P->leftChild == K) {
470             // RL Rotation
471             SplayDoubleRotateWithRight(GP);
472         } else if (GP->rightChild == P && P->rightChild == K) {
473             // R-Zig-Zig
474             ZigZigWithRight(GP);
475         }
476         // Return the new root if GP == T
477         if(GP == T){
478             return K;
479         }
480     }
481     if (T->leftChild == K) {
482         // LL Rotation
483         T = SplaySingleRotateWithLeft(T);
484     } else if (T->rightChild == K) {
485         // RR Rotation
486         T = SplaySingleRotateWithRight(T);
487     }
488     return T;
489 }
490 // Insert operation of Splay Tree
491 SplayTreeNode* SplayTreeInsert(int value, SplayTreeNode* T) {
492     // First insert the element just like Binery Search Tree
493     T = PreInsert(value, T);
494     // Then do the Splay
495     T = Splay(value, T);
496 }
497 // Splay operation of Splay Tree
498 SplayTreeNode* Splay(SplayTreeNode* node, SplayTreeNode* T) {
499       SplayTreeNode* K = node;
500     // Parent node
501     SplayTreeNode* P = NULL;
502     // Grandparent node
503     SplayTreeNode* GP = NULL;
504     // If node doesn‘t exist
505     if(K == NULL){
506         return T;
507     }
508     // Do rotation until K arrives at root or is the child of root
509     while (T->leftChild != K && T->rightChild != K) {
510         P = K->parent;
511         // Break the loop if just need single rotation
512         if(P==NULL||P->parent==NULL){
513             break;
514         }
515         GP = P->parent;
516         if (GP->leftChild == P && P->leftChild == K) {
517             // L-Zig-Zig
518             ZigZigWithLeft(GP);
519         } else if (GP->leftChild == P && P->rightChild == K) {
520             // LR Rotation
521             SplayDoubleRotateWithLeft(GP);
522         } else if (GP->rightChild == P && P->leftChild == K) {
523             // RL Rotation
524             SplayDoubleRotateWithRight(GP);
525         } else if (GP->rightChild == P && P->rightChild == K) {
526             // R-Zig-Zig
527             ZigZigWithRight(GP);
528         }
529         // Return the new root if GP == T
530         if(GP == T){
531             return K;
532         }
533     }
534     if (T->leftChild == K) {
535         // LL Rotation
536         T = SplaySingleRotateWithLeft(T);
537     } else if (T->rightChild == K) {
538         // RR Rotation
539         T = SplaySingleRotateWithRight(T);
540     }
541     return T;
542 }
543 // Delete operation of Splay Tree
544 SplayTreeNode* SplayTreeDelete(int value, SplayTreeNode* T) {
545     // If T is NULL
546     if (!T) {
547         return NULL;
548     }
549     // First do the Splay operation
550     T = Splay(value, T);
551     // Leftchild of root
552     SplayTreeNode* L = T->leftChild;
553     // Rightchild of root
554     SplayTreeNode* R = T->rightChild;
555     // If the tree doesn‘t have rightchild
556     if(R==NULL){
557         R = L;
558         if (L) {
559             R->parent = NULL;
560         }
561     }
562     else{
563         R->parent = NULL;
564         // Find the minimum element of R
565         R = Splay(SplayTreeFindMin(R), R);
566         R-> leftChild = L;
567         if(L){
568             L->parent = R;
569         }
570     }
571     // Delete the element
572     delete T;
573     return R;
574 }

 







以上是关于BST, AVL Tree 和 Splay Tree 的实现的主要内容,如果未能解决你的问题,请参考以下文章

430BST and Splay Tree

Splay Tree

PTA Root of AVL Tree (AVL树模板+四种旋转+指针)

Splay Tree——动机和宏观策略

Splay Tree(伸展树)

伸展树(splay tree)