1 ///AVL树模板 2 typedef struct Node ///树的节点 3 { 4 int val,data; 5 int h; ///以当前结点为根结点的数的高度 6 int bf; ///平衡因子(左子树高度与右子树高度之差) 7 Node *left,*right; 8 }Node; 9 10 class AvlTree ///alv树,树中太多函数,用类来实现容易一些 11 { 12 private: 13 Node *root; ///树的根节点 14 public: 15 void Init() ///初始化树 16 { 17 root=NULL; 18 } 19 int Height(Node *T) ///取一个节点的高度 20 { 21 if (T==NULL) return 0; 22 return T->h; 23 } 24 int Bf(Node *T) ///计算一个节点的平衡因子 25 { 26 if (T->left==T->right) return 0; 27 if (T->left==NULL) return -(T->right->h); ///这里一定取负数(左子树高度与右子树高度之差) 28 if (T->right==NULL) return T->left->h; 29 return (T->left->h)-(T->right->h); 30 } 31 ///四种旋转,不知为什么,自己多画一下就知道了。 32 Node *LL_rotate(Node *T) ///单向右旋平衡处理LL:由于在*T的左子树根结点的左子树上插入结点 33 { 34 Node *B=T->left; 35 T->left=B->right; 36 B->right=T; 37 T->h=max(Height(T->left),Height(T->right))+1; 38 B->h=max(Height(B->left),Height(T->right))+1; 39 T->bf=Bf(T); 40 B->bf=Bf(B); 41 return B; 42 } 43 Node *RR_rotate(Node *T) ///单向左旋平衡处理RR:由于在*T的右子树根结点的右子树上插入结点 44 { 45 Node *B=T->right; 46 T->right=B->left; 47 B->left=T; 48 T->h=max(Height(T->left),Height(T->right))+1; 49 B->h=max(Height(B->left),Height(T->right))+1; 50 T->bf=Bf(T); 51 B->bf=Bf(B); 52 return B; 53 } 54 Node *LR_rotate(Node *T) ///双向旋转平衡处理LR:由于在*T的左子树根结点的右子树上插入结点 55 { 56 T->left=RR_rotate(T->left); 57 T=LL_rotate(T); 58 return T; 59 } 60 Node *RL_rotate(Node *T) ///双向旋转平衡处理RL:由于在*T的右子树根结点的左子树上插入结点 61 { 62 T->right=LL_rotate(T->right); 63 T=RR_rotate(T); 64 return T; 65 } 66 void Insert(int v,int e) ///root是private,所以不能从主函数传入 67 { 68 Insert(root,v,e); 69 } 70 void Insert(Node *&T,int v,int e) ///插入新节点 71 { 72 if (T==NULL) 73 { 74 T=(Node *)malloc(sizeof(Node)); 75 T->h=1; 76 T->bf=0; 77 T->val=v; 78 T->data=e; 79 T->left=T->right=NULL; 80 return ; 81 } 82 if (e<T->data) Insert(T->left,v,e); 83 else Insert(T->right,v,e); 84 T->h=max(Height(T->left),Height(T->right))+1; ///计算节点高度 85 T->bf=Bf(T); ///计算平衡因子 86 if (T->bf>1||T->bf<-1) ///调整平衡,四种调整反法 87 { 88 if (T->bf>1&&T->left->bf>0) T=LL_rotate(T); ///如果T->bf > 1 则肯定有左儿子 89 if (T->bf<-1&&T->right->bf<0) T=RR_rotate(T); ///如果T->bf < -1 则肯定有右儿子 90 if (T->bf>1&&T->left->bf<0) T=LR_rotate(T); 91 if (T->bf<-1&&T->right>0) T=RL_rotate(T); 92 } 93 } 94 void Find(int flag) ///flag=1为找最大值,否则找最小值 95 { 96 if (root==NULL) 97 { 98 printf("0\n"); 99 return ; 100 } 101 Node *temp=root; 102 if (flag) ///最大值一定最右边 103 { 104 while (temp->right) 105 temp=temp->right; 106 } 107 else 108 { 109 while (temp->left) 110 temp=temp->left; 111 } 112 printf("%d\n",temp->val); 113 Delete(root,temp->data); ///删除相应节点 114 } 115 void Delete(Node *&T,int e) 116 { 117 if (T==NULL) return ; 118 if (e<T->data) Delete(T->left,e); 119 else if (e>T->data) Delete(T->right,e); 120 else ///找到删除的节点 121 { 122 if (T->left&&T->right) ///删除的节点左右都还有节点 123 { 124 Node *temp=T->left; ///把左子树的最大值当做当前节点 125 while (temp->right) temp=temp->right; ///找最大值 126 T->val=temp->val; 127 T->data=temp->data; 128 Delete(T->left,temp->data); ///左子树最大值已近改为当前根节点,应该删除原来位置 129 } 130 else 131 { 132 Node *temp=T; 133 if (T->left) T=T->left; ///删除节点只存在左子树 134 else if (T->right) T=T->right; ///删除节点只有右子树 135 else ///删除节点没有孩子 136 { 137 free(T); 138 T=NULL; 139 } 140 if (T) free(temp); 141 return ; 142 } 143 } 144 T->h=max(Height(T->left),Height(T->right))+1; 145 T->bf=Bf(T); 146 if (T->bf>1||T->bf<-1) ///删除后一定要调整 147 { 148 if (T->bf>1&&T->left->bf>0) T=LL_rotate(T); 149 if (T->bf<-1&&T->right->bf<0) T=RR_rotate(T); 150 if (T->bf>1&&T->left->bf<0) T=LR_rotate(T); 151 if (T->bf<-1&&T->right>0) T=RL_rotate(T); 152 } 153 } 154 void Free() ///由于内存是malloc出来的,最后一定要释放 155 { 156 FreeNode(root); 157 } 158 void FreeNode(Node *T) 159 { 160 if (T==NULL) return ; 161 if (T->right) FreeNode(T->right); 162 if (T->left) FreeNode(T->left); 163 free(T); 164 } 165 };