码迷,mamicode.com
首页 > 其他好文 > 详细

AVL树模板

时间:2016-08-08 19:31:20      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

  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 };

 

AVL树模板

标签:

原文地址:http://www.cnblogs.com/pblr/p/5750564.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!