AVL Tree 的实现

http://blog.csdn.net/zk_sima/article/details/6268127


首先 AVL 树是平衡二叉搜索树,所以首先 必须满足搜索树,即l_child值<parent值<=r_child值。这个在前面已经实现了。插入和删除不停的递归就可以。

其次 AVL 树是平衡二叉树,他的平衡条件是左右子树的深度之差小于2.而关键问题在怎么计算深度之差。

一般的方法都是通过平衡度来衡量的。而平衡度怎么得到呢,一般是通过左右子树的深度差得到。其实别人怎么得到平衡度我也没搞明白,不过在这里我是参考了一中思路,就是在每个节点中 包含它自己的高度,而没有直接包含平衡度。

节点的结构:

[cpp]  view plain  copy
  1. template<typename T>  
  2. struct node  
  3. {  
  4.     typedef typename node*  PVOID;  
  5.     PVOID                   l_child;//指向左子树  
  6.     PVOID                   r_child;//右子树指针  
  7.     T                       value;//节点值  
  8. private:  
  9.     int                     height;//节点高度  
  10. public:  
  11.     int getHeight()//得到该节点的高度  
  12.     {  
  13.         if(NULL==this)  
  14.             return 0;  
  15.         else  
  16.             return this->height;  
  17.     }  
  18.     void setHeight()//设置节点的高度  
  19.     {  
  20.         if(NULL==this)  
  21.             return ;  
  22.         int lh,rh;  
  23.         lh=this->l_child->getHeight();  
  24.         rh=this->r_child->getHeight();  
  25.         this->height=lh>rh?(lh+1):(rh+1);  
  26.         return ;  
  27.     }  
  28.     bool ifBalance()//判断该节点是否破坏平衡条件  
  29.     {  
  30.         int flag=this->l_child->getHeight()-this->r_child->getHeight();  
  31.         return flag<2&&flag>-2;  
  32.     }  
  33.     node(T key):l_child(0),r_child(0),value(key),height(1){}  
  34. };  
 

其实AVL 的算法很简单,AVL算法的示意图和神马的前人都给你画出来了,而实现这些算法,主要就在内存分配上,和指针的处理上。

而这里面 最主要的就是 高度的处理上面。

AVL的基本算法:

[cpp]  view plain  copy
  1. void ll_rotation(PNODE& pNode)//左左  
  2.     {  
  3.         PNODE tempNode=pNode->l_child->r_child;  
  4.         pNode->l_child->r_child=pNode;  
  5.         pNode=pNode->l_child;  
  6.         pNode->r_child->l_child=tempNode;  
  7.         pNode->r_child->setHeight();  
  8.         pNode->setHeight();  
  9.     }     
  10.     void lr_rotation(PNODE& pNode)//左右  
  11.     {  
  12.         PNODE tempNode=pNode->l_child->r_child->l_child;  
  13.         pNode->l_child->r_child->l_child=pNode->l_child;  
  14.         pNode->l_child=pNode->l_child->r_child;  
  15.         pNode->l_child->l_child->r_child=tempNode;  
  16.         pNode->l_child->l_child->setHeight();  
  17.         pNode->l_child->setHeight();  
  18.         ll_rotation(pNode);  
  19.     }  
  20.     void rl_rotation(PNODE& pNode)//右左  
  21.     {  
  22.         PNODE tempNode=pNode->r_child->l_child->r_child;  
  23.         pNode->r_child->l_child->r_child=pNode->r_child;  
  24.         pNode->r_child=pNode->r_child->l_child;  
  25.         pNode->r_child->r_child->l_child=tempNode;  
  26.         pNode->r_child->r_child->setHeight();  
  27.         pNode->r_child->setHeight();  
  28.         rr_rotation(pNode);  
  29.     }  
  30.     void rr_rotation(PNODE& pNode)//右右  
  31.     {  
  32.         PNODE tempNode=pNode->r_child->l_child;  
  33.         pNode->r_child->l_child=pNode;  
  34.         pNode=pNode->r_child;  
  35.         pNode->l_child->r_child=tempNode;  
  36.         pNode->l_child->setHeight();  
  37.         pNode->setHeight();  
  38.     }  
 

怎么让AVL树恢复平衡:

[cpp]  view plain  copy
  1. void rebalance(PNODE& pNode)//恢复树的平衡  
  2.     {  
  3.         if(pNode->l_child->getHeight()>pNode->r_child->getHeight())  
  4.         {  
  5.             if(pNode->l_child->l_child->getHeight()>pNode->l_child->r_child->getHeight())  
  6.                 return ll_rotation(pNode);  
  7.             else  
  8.                 return lr_rotation(pNode);  
  9.         }  
  10.         else  
  11.         {  
  12.             if(pNode->r_child->l_child->getHeight()>pNode->r_child->r_child->getHeight())  
  13.                 return rl_rotation(pNode);  
  14.             else  
  15.                 return rr_rotation(pNode);  
  16.         }  
  17.     }  
 

具体代码:

[cpp]  view plain  copy
  1. template<typename T>  
  2. struct node  
  3. {  
  4.     typedef typename node*  PVOID;  
  5.     PVOID                   l_child;//指向左子树  
  6.     PVOID                   r_child;//右子树指针  
  7.     T                       value;//节点值  
  8. private:  
  9.     int                     height;//节点高度  
  10. public:  
  11.     int getHeight()//得到该节点的高度  
  12.     {  
  13.         if(NULL==this)  
  14.             return 0;  
  15.         else  
  16.             return this->height;  
  17.     }  
  18.     void setHeight()//设置节点的高度  
  19.     {  
  20.         if(NULL==this)  
  21.             return ;  
  22.         int lh,rh;  
  23.         lh=this->l_child->getHeight();  
  24.         rh=this->r_child->getHeight();  
  25.         this->height=lh>rh?(lh+1):(rh+1);  
  26.         return ;  
  27.     }  
  28.     bool ifBalance()//判断该节点是否破坏平衡条件  
  29.     {  
  30.         int flag=this->l_child->getHeight()-this->r_child->getHeight();  
  31.         return flag<2&&flag>-2;  
  32.     }  
  33.     node(T key):l_child(0),r_child(0),value(key),height(1){}  
  34. };  
  35. template<class T>  
  36. class AVLTree  
  37. {  
  38. public:  
  39.     typedef typename node<T>*   PNODE;  
  40. private:  
  41.     PNODE root;//跟节点,对于一颗搜索二叉树来说只需要保存跟节点 就可以遍历整棵树  
  42. private://这些函数负责 内存管理  
  43.     PNODE createNode(T  value)//分配内存 ,并构造  
  44.     {  
  45.         PNODE pNode=(PNODE)malloc(sizeof(node<T>));//首先分配内存  
  46.         new(pNode) node<T>(value);//对这段内存进行构造  
  47.         return pNode;  
  48.     }  
  49.     void deallocNode(PNODE& pNode)//释放空间  
  50.     {  
  51.         free(pNode);  
  52.         pNode=0;  
  53.     }  
  54. private:  
  55.     void ll_rotation(PNODE& pNode)//左左  
  56.     {  
  57.         PNODE tempNode=pNode->l_child->r_child;  
  58.         pNode->l_child->r_child=pNode;  
  59.         pNode=pNode->l_child;  
  60.         pNode->r_child->l_child=tempNode;  
  61.         pNode->r_child->setHeight();  
  62.         pNode->setHeight();  
  63.     }     
  64.     void lr_rotation(PNODE& pNode)//左右  
  65.     {  
  66.         PNODE tempNode=pNode->l_child->r_child->l_child;  
  67.         pNode->l_child->r_child->l_child=pNode->l_child;  
  68.         pNode->l_child=pNode->l_child->r_child;  
  69.         pNode->l_child->l_child->r_child=tempNode;  
  70.         pNode->l_child->l_child->setHeight();  
  71.         pNode->l_child->setHeight();  
  72.         ll_rotation(pNode);  
  73.     }  
  74.     void rl_rotation(PNODE& pNode)//右左  
  75.     {  
  76.         PNODE tempNode=pNode->r_child->l_child->r_child;  
  77.         pNode->r_child->l_child->r_child=pNode->r_child;  
  78.         pNode->r_child=pNode->r_child->l_child;  
  79.         pNode->r_child->r_child->l_child=tempNode;  
  80.         pNode->r_child->r_child->setHeight();  
  81.         pNode->r_child->setHeight();  
  82.         rr_rotation(pNode);  
  83.     }  
  84.     void rr_rotation(PNODE& pNode)//右右  
  85.     {  
  86.         PNODE tempNode=pNode->r_child->l_child;  
  87.         pNode->r_child->l_child=pNode;  
  88.         pNode=pNode->r_child;  
  89.         pNode->l_child->r_child=tempNode;  
  90.         pNode->l_child->setHeight();  
  91.         pNode->setHeight();  
  92.     }  
  93.     void rebalance(PNODE& pNode)//恢复树的平衡  
  94.     {  
  95.         if(pNode->l_child->getHeight()>pNode->r_child->getHeight())  
  96.         {  
  97.             if(pNode->l_child->l_child->getHeight()>pNode->l_child->r_child->getHeight())  
  98.                 return ll_rotation(pNode);  
  99.             else  
  100.                 return lr_rotation(pNode);  
  101.         }  
  102.         else  
  103.         {  
  104.             if(pNode->r_child->l_child->getHeight()>pNode->r_child->r_child->getHeight())  
  105.                 return rl_rotation(pNode);  
  106.             else  
  107.                 return rr_rotation(pNode);  
  108.         }  
  109.     }  
  110.     void insert(PNODE &pParent,PNODE pNode)//插入节点  
  111.     {  
  112.         if(0==pParent)  
  113.         {  
  114.             pParent=pNode;  
  115.             return ;  
  116.         }  
  117.         if(pNode->value>=pParent->value)  
  118.             insert(pParent->r_child,pNode);  
  119.         else if(pNode->value <pParent->value)  
  120.             insert(pParent->l_child,pNode);  
  121.         pParent->setHeight();  
  122.         if(pParent->ifBalance())  
  123.             return ;  
  124.         else  
  125.             rebalance(pParent);  
  126.     }  
  127.     void remove(PNODE& pParent,T value)//删除某个节点  
  128.     {  
  129.         if(0==pParent)  
  130.             return ;  
  131.         if(value>pParent->value)  
  132.             remove(pParent->r_child,value);  
  133.         else if(value<pParent->value)  
  134.             remove(pParent->l_child,value);  
  135.         else  
  136.         {  
  137.             if(0!=pParent->l_child&&0!=pParent->r_child)  
  138.             {  
  139.                 PNODE p=pParent->r_child;  
  140.                 while(p->l_child)  
  141.                     p=p->l_child;  
  142.                 pParent->value=p->value;  
  143.                 p->value=value;  
  144.                 remove(pParent->r_child,value);  
  145.             }  
  146.             else   
  147.             {  
  148.                 if(0!=pParent->l_child&&0==pParent->r_child)  
  149.                 {  
  150.                     PNODE tempNode=pParent;  
  151.                     pParent=pParent->l_child;  
  152.                     return this->deallocNode(tempNode);  
  153.                 }  
  154.                 else   
  155.                 {  
  156.                     if(0!=pParent->r_child&&0==pParent->l_child)  
  157.                     {  
  158.                         PNODE tempNode=pParent;  
  159.                         pParent=pParent->r_child;  
  160.                         return this->deallocNode(tempNode);  
  161.                     }  
  162.                     else if(0==pParent->r_child&&0==pParent->l_child)  
  163.                         return this->deallocNode(pParent);  
  164.                 }  
  165.             }  
  166.         }  
  167.         pParent->setHeight();  
  168.         if(pParent->ifBalance())  
  169.             return ;  
  170.         return rebalance(pParent);  
  171.     }  
  172. public:  
  173.     AVLTree():root(0){}//构造函数  
  174.     void insert(T value)//插入值  
  175.     {  
  176.         PNODE pNode=this->createNode(value);  
  177.         insert(root,pNode);  
  178.     }  
  179.     void remove(T value)//删除值  
  180.     {  
  181.         remove(root,value);  
  182.     }  
  183.     T getMax()//得到最大值  
  184.     {  
  185.         if(0==root)  
  186.             return T(0);  
  187.         T max=root->value;  
  188.         PNODE p=root;  
  189.         while(p)  
  190.         {  
  191.             max=p->value;  
  192.             p=p->r_child;  
  193.         }  
  194.         return max;  
  195.     }  
  196.     T getMin()//得到最小值  
  197.     {  
  198.         if(0==root)  
  199.             return T(0);  
  200.         T min=root->value;  
  201.         PNODE p=root;  
  202.         while(p)  
  203.         {  
  204.             min=p->value;  
  205.             p=p->l_child;  
  206.         }  
  207.         return min;  
  208.     }  
  209. };  
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值