1. 程式人生 > >04-樹5 Root of AVL Tree

04-樹5 Root of AVL Tree

oot eof sin 要求 avltree std %d tty pre

  這道題目要求找出AVL樹的根節點,重點考查了AVL樹的旋轉(右單旋、左單旋、右-左雙旋和左-右雙旋)與插入操作。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 typedef struct AVLNode *AVLTree;
  5 typedef int ElementType;
  6 struct AVLNode {
  7     ElementType Data;
  8     AVLTree Left, Right;
  9     int Height;    // 樹高 
 10 };
11 12 int Max(int a, int b); 13 int GetHeight(AVLTree T); 14 AVLTree SingleLeftRotation(AVLTree A); 15 AVLTree SingleRightRotation(AVLTree A); 16 AVLTree DoubleLeftRightRotation(AVLTree A); 17 AVLTree DoubleRightLeftRotation(AVLTree A); 18 AVLTree Insert(AVLTree T, ElementType X); 19 20 int
main() 21 { 22 int N, i; 23 ElementType data; 24 AVLTree T; 25 26 scanf("%d", &N); 27 for ( i = 0; i < N; i++ ) { 28 scanf("%d", &data); 29 T = Insert(T, data); 30 } 31 printf("%d", T->Data); 32 33 return 0; 34 } 35
36 AVLTree Insert(AVLTree T, ElementType X) 37 { 38 if ( !T ) { 39 T = (AVLTree)malloc(sizeof(struct AVLNode)); 40 T->Data = X; T->Height = 0; 41 T->Left = T->Right = NULL; 42 } 43 else { 44 if ( X < T->Data ) { 45 // 插入 T 的左子樹 46 T->Left = Insert(T->Left, X); 47 // 如果需要 左旋 48 if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 ) 49 if ( X < T->Left->Data ) // 左單旋 50 T = SingleLeftRotation(T); 51 else // 左-右雙旋 52 T = DoubleLeftRightRotation(T); 53 } 54 else if ( X > T->Data ) { 55 // 插入 T 的右子樹 56 T->Right = Insert(T->Right, X); 57 // 如果需要右旋 58 if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 ) 59 if ( X > T->Right->Data ) // 右單旋 60 T = SingleRightRotation(T); 61 else // 右-左雙旋 62 T = DoubleRightLeftRotation(T); 63 } 64 /* else X == T->Data 無須插入 */ 65 } 66 // 更新樹的高度 67 T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1; 68 69 return T; 70 } 71 72 AVLTree DoubleRightLeftRotation(AVLTree A) 73 { 74 // B 與 C 做 左單旋,C 被返回 75 A->Right = SingleLeftRotation(A->Right); 76 // A 與 C 做 右單旋, C 被返回 77 return SingleRightRotation(A); 78 } 79 80 AVLTree DoubleLeftRightRotation(AVLTree A) 81 { /* 註意:A必須有一個左子結點B,且B必須有一個右子結點C */ 82 /* 將A、B與C做兩次單旋,返回新的根結點C */ 83 84 // B 與 C 做 右單旋, C被返回 85 A->Left = SingleRightRotation(A->Left); 86 // A 與 C 做 左單旋, C被返回 87 return SingleLeftRotation(A); 88 } 89 90 AVLTree SingleRightRotation(AVLTree A) 91 { 92 AVLTree B = A->Right; 93 A->Right = B->Left; 94 B->Left = A; 95 A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1; 96 B->Height = Max( A->Height, GetHeight(B->Right) ) + 1; 97 98 return B; 99 } 100 101 AVLTree SingleLeftRotation(AVLTree A) 102 { /* 註意:A必須有一個左子結點B */ 103 /* 將A與B做左單旋,更新A與B的高度,返回新的根結點B */ 104 AVLTree B = A->Left; 105 A->Left = B->Right; 106 B->Right = A; 107 A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1; 108 B->Height = Max( GetHeight(B->Left), A->Height ) + 1; 109 110 return B; 111 } 112 113 int GetHeight(AVLTree T) 114 { 115 if ( !T ) return 0; 116 return T->Height; 117 } 118 119 int Max(int a, int b) 120 { 121 return ( a > b ? a : b ); 122 }

04-樹5 Root of AVL Tree