平衡二叉树(Self-balancing Binary Search Tree)
Date: 2019-04-11 18:49:18
AVL树的基本操作
1 //存储结构 2 struct node 3 { 4 int data; 5 int height; //记录当前子树的高度(叶子->根) 6 //存储平衡因子的话,无法通过其子树算得该树的平衡因子 7 node *lchild, *rchild; 8 }; 9 10 11 //新建结点 12 node *newNode(int v) 13 { 14 node *root = new node; 15 root->data = v; 16 root->height = 1; 17 root->lchild = root->rchild = NULL; 18 return root; 19 } 20 21 //获取当前结点所在高度 22 int GetHeight(node *root) 23 { 24 if(root == NULL) 25 return 0; 26 return root->height; 27 } 28 29 //计算结点的平衡因子 30 int GetBalanceFactors(node *root) 31 { 32 return GetHeight(root->lchild)-GetHeight(root->rchild); 33 } 34 35 //更新结点高度 36 void UpdataHeight(node *root) 37 { 38 root->height = max(GetHeight(root->lchild), GetHeight(root->rchild))+1; 39 } 40 41 //查找 42 void Search(node *root, int x) 43 { 44 if(root == NULL) 45 return; 46 if(x == root->data) 47 //visit 48 else if(x < root->data) 49 Search(root->lchild, x); 50 else 51 Search(root->rchild, x); 52 } 53 54 //左右旋互为逆操作 55 //左旋 56 void LeftRotation(node *&root) 57 { 58 node *temp = root->lchild; //temp指向新的根结点B 59 root->rchild = temp->lchild; //B的左子树给A的右子树 60 temp->lchild = root; //B的左子树变为A 61 UpdataHeight(root); //更新结点高度 62 UpdataHeight(temp); 63 root = temp; //令B成为新的根结点 64 } 65 66 //右旋 67 void RightRotation(node *&root) 68 { 69 node *temp = root->lchild; 70 root->lchild = temp->rchild; 71 temp->rchild = root; 72 UpdataHeight(root); 73 UpdataHeight(temp); 74 root = temp; 75 } 76 77 /* 78 1.LL: A==+2, A->lchild=+1 79 A作为root进行右旋 80 2.LR: A==+2, A->lchild=-1 81 A->lchild作为root进行左旋 --> 转化为LL 82 A作为root进行右旋 83 3.RR: A==-2, A->rchild=-1 84 A作为root进行左旋 85 4.RL: A==-2, A->rchild=+1 86 A->rchild作为root进行右旋 --> 转化为RR 87 A作为root进行左旋 88 */ 89 90 //插入 91 void Insert(node *&root, int v) 92 { 93 if(root == NULL) 94 { 95 root = newNode(v); 96 return; 97 } 98 if(v < root->data) 99 { 100 Insert(root->lchild, v); 101 UpdataHeight(root); //更新树高 102 if(GetBalanceFactor(root) == 2) 103 { 104 if(GetBalanceFactor(root->lchild) == 1) 105 RightRotation(root); 106 else 107 { 108 LeftRotation(root->lchild); 109 RightRotation(root); 110 } 111 } 112 } 113 else 114 { 115 Insert(root->rchild, v); 116 UpdataHeight(root); 117 if(GetBalanceFactor(root) == -2) 118 { 119 if(GetBalanceFactor(root->rchild) == -1) 120 LeftRotation(root); 121 else 122 { 123 RightRotation(root->rchild); 124 LeftRotation(root); 125 } 126 } 127 } 128 } 129 130 //建立 131 node *Create(int data[], int n) 132 { 133 node *root = NULL; 134 for(int i=0; i<n; i++) 135 Insert(root, data[i]); 136 return root; 137 }
判断一棵树是否为AVL树
1 #include <cstdio> 2 const int M = 10; 3 int pre[M]={50,38,30,45,40,48,70,60,75,80}; 4 int in[M]={30,38,40,45,48,50,60,70,75,80}; 5 struct node 6 { 7 int data; 8 node *lchild, *rchild; 9 }; 10 11 node *Create(int preL, int preR, int inL, int inR) 12 { 13 if(preL > preR) 14 return NULL; 15 node *root = new node; 16 root->data = pre[preL]; 17 int k; 18 for(k=inL; k<=inR; k++) 19 if(in[k] == root->data) 20 break; 21 int numLeft = k-inL; 22 root->lchild = Create(preL+1, preL+numLeft, inL, k-1); 23 root->rchild = Create(preL+numLeft+1, preR, k+1, inR); 24 } 25 26 int IsAvl = true; 27 int IsAVL(node *root) 28 { 29 if(root == NULL) 30 return -1; 31 int bl = IsAVL(root->lchild)+1; 32 int br = IsAVL(root->rchild)+1; 33 if(bl-br>1 || bl-br<-1) 34 IsAvl = false; 35 return bl>br?bl:br; 36 } 37 38 int main() 39 { 40 #ifdef ONLINE_JUDGE 41 #else 42 freopen("Test.txt", "r", stdin); 43 #endif 44 45 node *root = Create(0,M-1,0,M-1); 46 IsAVL(root); 47 if(IsAvl) 48 printf("Yes."); 49 else 50 printf("No."); 51 52 return 0; 53 }