AVL 平衡二叉树
来源:互联网 发布:手游推荐知乎 编辑:程序博客网 时间:2024/04/30 05:11
#include "stdio.h"#include "stdlib.h"typedef struct _Node{int data;int h;struct _Node* lf;struct _Node* rt;}Node, *pNode;int ht(pNode a){return a?a->h:0;}int mh(pNode a, pNode b){return ht(a)>ht(b)?ht(a):ht(b);}void LL(pNode* root){pNode t, w = *root;t = w->lf;w->lf = t->rt;t->rt = w;*root = t;w->h = mh(w->lf, w->rt) +1; //移到了右边,更新高度}void RR(pNode* root){pNode t, w = *root;t = w->rt;w->rt = t->lf;t->lf = w;*root = t;w->h = mh(w->lf, w->rt) +1; //移到了左边,更新高度}void LR(pNode* root){RR(&((*root)->lf)); //这句后面是否需要加一句更新高度?不需要LL(root);}void RL(pNode* root){LL(&((*root)->rt));RR(root);}void rotate(pNode* root){ //旋转平衡pNode w = *root;if(ht(w->lf) - ht(w->rt) == 2){if(ht(w->lf->lf) > ht(w->lf->rt))LL(root);elseLR(root);}if(ht(w->rt) - ht(w->lf) == 2){if(ht(w->rt->rt) > ht(w->rt->lf))RR(root);elseRL(root);}w = *root; //为什么要这样?因为在前面旋转时,*root已经改变,w和*root已经不是指向同一个地方w->h = mh(w->lf, w->rt) +1; //更新高度}void insert(pNode* root, int val){pNode w = *root;if(!w){w = (pNode)malloc(sizeof(Node));w->data = val;w->h = 1;w->lf = w->rt = 0;*root = w;return;}if(val > w->data)insert(&(w->rt), val);elseinsert(&(w->lf), val);rotate(root);}void remove(pNode* root, int val){pNode t, w = *root;if(!w) return;if(val == w->data){if(w->rt == 0){ //如果节点只有左子树,直接删掉,并将其左子树接上*root = w->lf;free(w);return;}t = w->rt; //否则,用该节点右子树的最左子节点来代替,这是个递归的过程while(t->lf) t = t->lf;w->data = t->data;remove(&(w->rt), t->data); //用右子树的最左节点来代替后,那还得用右子树的最左节点的右子树的最左节点来代替……递归}else if(val > w->data)remove(&(w->rt), val);else remove(&(w->lf), val);rotate(root);}void show(pNode root){if(!root) return;printf("%d ", root->data);show(root->lf);show(root->rt);}void main(){int i;pNode root = 0;for(i=20; i>=0; i--)insert(&root, i);show(root);printf("\n");remove(&root, 7);remove(&root, 13);remove(&root, 19);remove(&root, 16);show(root);printf("\n");}
关于高度更新:
经过LL旋转,A的高度更新了,但B的高度没更新,是否需要再写一句代码更新呢?不需要。因为插入B1后,B1高度变成h,然后回退到B节点,更新高度为h+1,此时以B为根的树还是平衡的,不需要旋转,但继续回退到A时,发现不平衡,才开始执行LL,也就是说,在执行LL操作前,B的高度已经更新为h+1,LL操作后,不需要再更新B的高度。
即:LL操作中,只更新降为右子树的节点(例如上图的A点)即可。不需要再写一句来更新根(B点)的高度。
RR操作与LL操作相同,只需更新降为左子树的节点(如上图的A)即可
LR操作是先RR操作再LL操作。通过上面可知,RR操作时,上图中B的高度更新了,再进行LL操作时,A的高度也更新了,最后C成了树根,高度没更新,那是否也和上面一样不需要再写一句更新呢?答案是需要。
C在其子树插入节点后,树高更新为h,等LR操作结束后,C成了树根,其高度应该为h+1,所以需要再写一句更新高度。
RL操作与LR操作同理,过程中会先更新B的高度,再更新A的高度,最后需要再写一句来更新C的高度
更多参考:
http://www.asiteof.me/2010/06/avl/
http://www.asiteof.me/2010/06/avl/
- - - - - - - - - - - - - - - - -- - - - - - - -- - - - - - - - - - - - - -- -- - -- - - - - - - - - - -
进一步浓缩:
#include "stdio.h"#include "stdlib.h"typedef struct _Node{int val;int h;struct _Node* ch[2];}Node, *pNode;int ht(pNode r){return r?r->h:0;}void update(pNode r){r->h = (ht(r->ch[0])>ht(r->ch[1])?ht(r->ch[0]):ht(r->ch[1])) + 1;}void xxx(pNode* r, int op){ //0, LL; 1, RR;pNode t, w = *r;t = w->ch[op];w->ch[op] = t->ch[!op];t->ch[!op] = w;*r = t;update(w);}void zzz(pNode* r, int op){ //0, LR; 1, RL;xxx(&((*r)->ch[op]), !op);xxx(r, op);}void rotate(pNode* r){int op;pNode w = *r;for(op=0; op<2; op++){if(ht(w->ch[op])-ht(w->ch[!op]) == 2){if(ht(w->ch[op]->ch[op]) > ht(w->ch[op]->ch[!op]))xxx(r, op);elsezzz(r, op);}}update(*r);}void insert(pNode* r, int val){pNode w = *r;if(!w){w = (pNode)malloc(sizeof(Node));w->val = val;w->h = 1;w->ch[0] = w->ch[1] = 0;*r = w;return;}if(val > w->val)insert(&(w->ch[1]), val);elseinsert(&(w->ch[0]), val);rotate(r);}void del(pNode* r, int val){pNode t, w = *r;if(!w) return;if(val == w->val){if(!(w->ch[1])){*r = w->ch[0];return;}t = w->ch[1];while(t->ch[0]) t = t->ch[0];w->val = t->val;del(&(w->ch[1]), t->val);}else if(val > w->val)del(&(w->ch[1]), val);elsedel(&(w->ch[0]), val);update(w);}void show(pNode r){if(!r) return;printf("%d ", r->val);show(r->ch[0]);show(r->ch[1]);}void destroy(pNode r){if(!r) return;destroy(r->ch[0]);destroy(r->ch[1]);free(r);}void main(){int i;pNode root = 0;for(i=0; i<20; i++)insert(&root, i);show(root); printf("\n");del(&root, 3);del(&root, 7);del(&root, 10);show(root); printf("\n");}
- AVL 平衡二叉树
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- AVL 平衡二叉树
- avl平衡二叉树
- 二叉平衡树AVL
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- 平衡二叉树 AVL
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- 二叉平衡树AVL
- AVL平衡二叉树
- 平衡二叉树(AVL)
- 平衡二叉树AVL
- remake学习笔记
- Java 得到一个类里面的方法和属性
- 第一章小计
- 觉得很有用 粘下来看看 对应届生作用大点
- 学会订阅实时书签,让信息随心而动!
- AVL 平衡二叉树
- win7不能删除文件夹(您需要来自administrators的权限才能对此文件夹进行更改)
- 关于hudson上的job迁移-(job migration of hudson)
- 【flex4.6将移动开发进行到底】第一章第一节建立手机项目
- Android 类似于windows打开文件对话框的实现
- GridView支持复制与粘贴
- spring3.x中jar包的说明
- The War&&贪心算法
- 程序员必知的八大排序