AVL Tree 的实现
2016-06-28 14:54
239 查看
http://blog.csdn.net/zk_sima/article/details/6268127
首先 AVL 树是平衡二叉搜索树,所以首先 必须满足搜索树,即l_child值<parent值<=r_child值。这个在前面已经实现了。插入和删除不停的递归就可以。
其次 AVL 树是平衡二叉树,他的平衡条件是左右子树的深度之差小于2.而关键问题在怎么计算深度之差。
一般的方法都是通过平衡度来衡量的。而平衡度怎么得到呢,一般是通过左右子树的深度差得到。其实别人怎么得到平衡度我也没搞明白,不过在这里我是参考了一中思路,就是在每个节点中 包含它自己的高度,而没有直接包含平衡度。
节点的结构:
[cpp] view
plain copy
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的基本算法:
[cpp] view
plain copy
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树恢复平衡:
[cpp] view
plain copy
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);
}
}
具体代码:
[cpp] view
plain copy
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;
}
};
首先 AVL 树是平衡二叉搜索树,所以首先 必须满足搜索树,即l_child值<parent值<=r_child值。这个在前面已经实现了。插入和删除不停的递归就可以。
其次 AVL 树是平衡二叉树,他的平衡条件是左右子树的深度之差小于2.而关键问题在怎么计算深度之差。
一般的方法都是通过平衡度来衡量的。而平衡度怎么得到呢,一般是通过左右子树的深度差得到。其实别人怎么得到平衡度我也没搞明白,不过在这里我是参考了一中思路,就是在每个节点中 包含它自己的高度,而没有直接包含平衡度。
节点的结构:
[cpp] view
plain copy
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的基本算法:
[cpp] view
plain copy
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树恢复平衡:
[cpp] view
plain copy
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);
}
}
具体代码:
[cpp] view
plain copy
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;
}
};
相关文章推荐
- MIT Introduction to Algorithms 学习笔记(七)
- AVL树-scala实现
- [学习笔记]AVL平衡二叉树
- AVL树的旋转操作 图解 最详细
- 数据结构之平衡二叉树AVL
- BST与AVL的C++模板实现
- 基本数据结构之AVL树-简单实现
- 基本数据结构之AVL树
- 1066. Root of AVL Tree (25)
- AVL树的旋转
- AVL平衡树
- HackerRank Self Balancing Tree(AVL树)
- 平衡树之AVL树旋转
- C语言数据结构-树
- 平衡二叉树(AVL树)
- 1066. Root of AVL Tree (25)
- AVL树的实现
- 1066. Root of AVL Tree (25)【AVL树】——PAT (Advanced Level) Practise
- 1066. Root of AVL Tree (25)
- pat(A) 1066. Root of AVL Tree