http://blog.csdn.net/zk_sima/article/details/6268127
首先 AVL 树是平衡二叉搜索树,所以首先 必须满足搜索树,即l_child值<parent值<=r_child值。这个在前面已经实现了。插入和删除不停的递归就可以。
其次 AVL 树是平衡二叉树,他的平衡条件是左右子树的深度之差小于2.而关键问题在怎么计算深度之差。
一般的方法都是通过平衡度来衡量的。而平衡度怎么得到呢,一般是通过左右子树的深度差得到。其实别人怎么得到平衡度我也没搞明白,不过在这里我是参考了一中思路,就是在每个节点中 包含它自己的高度,而没有直接包含平衡度。
节点的结构:
- template<typename T>
- struct node
- {
- typedef typename node* PVOID;
- PVOID l_child;//指向左子树
- PVOID r_child;//右子树指针
- T value;//节点值
- private:
- int height;//节点高度
- public:
- int getHeight()//得到该节点的高度
- {
- if(NULL==this)
- return 0;
- else
- return this->height;
- }
- void setHeight()//设置节点的高度
- {
- if(NULL==this)
- return ;
- int lh,rh;
- lh=this->l_child->getHeight();
- rh=this->r_child->getHeight();
- this->height=lh>rh?(lh+1):(rh+1);
- return ;
- }
- bool ifBalance()//判断该节点是否破坏平衡条件
- {
- int flag=this->l_child->getHeight()-this->r_child->getHeight();
- return flag<2&&flag>-2;
- }
- node(T key):l_child(0),r_child(0),value(key),height(1){}
- };
其实AVL 的算法很简单,AVL算法的示意图和神马的前人都给你画出来了,而实现这些算法,主要就在内存分配上,和指针的处理上。
而这里面 最主要的就是 高度的处理上面。
AVL的基本算法:
- void ll_rotation(PNODE& pNode)//左左
- {
- PNODE tempNode=pNode->l_child->r_child;
- pNode->l_child->r_child=pNode;
- pNode=pNode->l_child;
- pNode->r_child->l_child=tempNode;
- pNode->r_child->setHeight();
- pNode->setHeight();
- }
- void lr_rotation(PNODE& pNode)//左右
- {
- PNODE tempNode=pNode->l_child->r_child->l_child;
- pNode->l_child->r_child->l_child=pNode->l_child;
- pNode->l_child=pNode->l_child->r_child;
- pNode->l_child->l_child->r_child=tempNode;
- pNode->l_child->l_child->setHeight();
- pNode->l_child->setHeight();
- ll_rotation(pNode);
- }
- void rl_rotation(PNODE& pNode)//右左
- {
- PNODE tempNode=pNode->r_child->l_child->r_child;
- pNode->r_child->l_child->r_child=pNode->r_child;
- pNode->r_child=pNode->r_child->l_child;
- pNode->r_child->r_child->l_child=tempNode;
- pNode->r_child->r_child->setHeight();
- pNode->r_child->setHeight();
- rr_rotation(pNode);
- }
- void rr_rotation(PNODE& pNode)//右右
- {
- PNODE tempNode=pNode->r_child->l_child;
- pNode->r_child->l_child=pNode;
- pNode=pNode->r_child;
- pNode->l_child->r_child=tempNode;
- pNode->l_child->setHeight();
- pNode->setHeight();
- }
怎么让AVL树恢复平衡:
- void rebalance(PNODE& pNode)//恢复树的平衡
- {
- if(pNode->l_child->getHeight()>pNode->r_child->getHeight())
- {
- if(pNode->l_child->l_child->getHeight()>pNode->l_child->r_child->getHeight())
- return ll_rotation(pNode);
- else
- return lr_rotation(pNode);
- }
- else
- {
- if(pNode->r_child->l_child->getHeight()>pNode->r_child->r_child->getHeight())
- return rl_rotation(pNode);
- else
- return rr_rotation(pNode);
- }
- }
具体代码:
- template<typename T>
- struct node
- {
- typedef typename node* PVOID;
- PVOID l_child;//指向左子树
- PVOID r_child;//右子树指针
- T value;//节点值
- private:
- int height;//节点高度
- public:
- int getHeight()//得到该节点的高度
- {
- if(NULL==this)
- return 0;
- else
- return this->height;
- }
- void setHeight()//设置节点的高度
- {
- if(NULL==this)
- return ;
- int lh,rh;
- lh=this->l_child->getHeight();
- rh=this->r_child->getHeight();
- this->height=lh>rh?(lh+1):(rh+1);
- return ;
- }
- bool ifBalance()//判断该节点是否破坏平衡条件
- {
- int flag=this->l_child->getHeight()-this->r_child->getHeight();
- return flag<2&&flag>-2;
- }
- node(T key):l_child(0),r_child(0),value(key),height(1){}
- };
- template<class T>
- class AVLTree
- {
- public:
- typedef typename node<T>* PNODE;
- private:
- PNODE root;//跟节点,对于一颗搜索二叉树来说只需要保存跟节点 就可以遍历整棵树
- private://这些函数负责 内存管理
- PNODE createNode(T value)//分配内存 ,并构造
- {
- PNODE pNode=(PNODE)malloc(sizeof(node<T>));//首先分配内存
- new(pNode) node<T>(value);//对这段内存进行构造
- return pNode;
- }
- void deallocNode(PNODE& pNode)//释放空间
- {
- free(pNode);
- pNode=0;
- }
- private:
- void ll_rotation(PNODE& pNode)//左左
- {
- PNODE tempNode=pNode->l_child->r_child;
- pNode->l_child->r_child=pNode;
- pNode=pNode->l_child;
- pNode->r_child->l_child=tempNode;
- pNode->r_child->setHeight();
- pNode->setHeight();
- }
- void lr_rotation(PNODE& pNode)//左右
- {
- PNODE tempNode=pNode->l_child->r_child->l_child;
- pNode->l_child->r_child->l_child=pNode->l_child;
- pNode->l_child=pNode->l_child->r_child;
- pNode->l_child->l_child->r_child=tempNode;
- pNode->l_child->l_child->setHeight();
- pNode->l_child->setHeight();
- ll_rotation(pNode);
- }
- void rl_rotation(PNODE& pNode)//右左
- {
- PNODE tempNode=pNode->r_child->l_child->r_child;
- pNode->r_child->l_child->r_child=pNode->r_child;
- pNode->r_child=pNode->r_child->l_child;
- pNode->r_child->r_child->l_child=tempNode;
- pNode->r_child->r_child->setHeight();
- pNode->r_child->setHeight();
- rr_rotation(pNode);
- }
- void rr_rotation(PNODE& pNode)//右右
- {
- PNODE tempNode=pNode->r_child->l_child;
- pNode->r_child->l_child=pNode;
- pNode=pNode->r_child;
- pNode->l_child->r_child=tempNode;
- pNode->l_child->setHeight();
- pNode->setHeight();
- }
- void rebalance(PNODE& pNode)//恢复树的平衡
- {
- if(pNode->l_child->getHeight()>pNode->r_child->getHeight())
- {
- if(pNode->l_child->l_child->getHeight()>pNode->l_child->r_child->getHeight())
- return ll_rotation(pNode);
- else
- return lr_rotation(pNode);
- }
- else
- {
- if(pNode->r_child->l_child->getHeight()>pNode->r_child->r_child->getHeight())
- return rl_rotation(pNode);
- else
- return rr_rotation(pNode);
- }
- }
- void insert(PNODE &pParent,PNODE pNode)//插入节点
- {
- if(0==pParent)
- {
- pParent=pNode;
- return ;
- }
- if(pNode->value>=pParent->value)
- insert(pParent->r_child,pNode);
- else if(pNode->value <pParent->value)
- insert(pParent->l_child,pNode);
- pParent->setHeight();
- if(pParent->ifBalance())
- return ;
- else
- rebalance(pParent);
- }
- void remove(PNODE& pParent,T value)//删除某个节点
- {
- if(0==pParent)
- return ;
- if(value>pParent->value)
- remove(pParent->r_child,value);
- else if(value<pParent->value)
- remove(pParent->l_child,value);
- else
- {
- if(0!=pParent->l_child&&0!=pParent->r_child)
- {
- PNODE p=pParent->r_child;
- while(p->l_child)
- p=p->l_child;
- pParent->value=p->value;
- p->value=value;
- remove(pParent->r_child,value);
- }
- else
- {
- if(0!=pParent->l_child&&0==pParent->r_child)
- {
- PNODE tempNode=pParent;
- pParent=pParent->l_child;
- return this->deallocNode(tempNode);
- }
- else
- {
- if(0!=pParent->r_child&&0==pParent->l_child)
- {
- PNODE tempNode=pParent;
- pParent=pParent->r_child;
- return this->deallocNode(tempNode);
- }
- else if(0==pParent->r_child&&0==pParent->l_child)
- return this->deallocNode(pParent);
- }
- }
- }
- pParent->setHeight();
- if(pParent->ifBalance())
- return ;
- return rebalance(pParent);
- }
- public:
- AVLTree():root(0){}//构造函数
- void insert(T value)//插入值
- {
- PNODE pNode=this->createNode(value);
- insert(root,pNode);
- }
- void remove(T value)//删除值
- {
- remove(root,value);
- }
- T getMax()//得到最大值
- {
- if(0==root)
- return T(0);
- T max=root->value;
- PNODE p=root;
- while(p)
- {
- max=p->value;
- p=p->r_child;
- }
- return max;
- }
- T getMin()//得到最小值
- {
- if(0==root)
- return T(0);
- T min=root->value;
- PNODE p=root;
- while(p)
- {
- min=p->value;
- p=p->l_child;
- }
- return min;
- }
- };