您的位置:首页 > 理论基础 > 数据结构算法

数据结构--------------AVLTree

2016-07-25 16:24 537 查看
一、AVLTree的概念

在计算机科学中,AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log
n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。AVL树得名于它的发明者 G.M. Adelson-Velsky 和 E.M. Landis,他们在 1962 年的论文 "An algorithm for the organization of information" 中发表了它。

二、AVLTree的性质

1. 左子树和右子树的高度之差的绝对值不超过1

2. 树中的每个左子树和右子树都是AVL树

3. 每个节点都有一个平衡因子(balance factor--bf),任一节点的平衡因子是-1,0,1。(每个节点的平衡因子等于右子树的高度减去左子树的高度 )

三、AVLTree的插入







四、实现如下:

#pragma once
#include<iostream>
#include<math.h>
using namespace std;
template<class K,class V>
struct AVLTreeNode
{
AVLTreeNode(K key,V value)
:_left(NULL)
,_right(NULL)
,_parent(NULL)
,_key(key)
,_value(value)
,bf(0)
{

}
AVLTreeNode* _left;
AVLTreeNode* _right;
AVLTreeNode* _parent;
K _key;
V _value;
int bf;  //平衡因子
};
template<class K,class V>
class AVLTree
{
typedef AVLTreeNode<K,V> Node;
public:
AVLTree()
:_root(NULL)
{
}
bool Insert(K key,V value)
{
if(_root==NULL)
{
_root=new Node(key,value);
return true;
}
Node* cur=_root;
Node* parent=NULL;
while(cur)
{
parent=cur;
if(cur->_key>key)
{
cur=cur->_left;
}
else if(cur->_key<key)
{
cur=cur->_right;
}
else
{
return false;
}
}
cur=new Node(key,value);
if(parent->_key>key)
{
parent->_left=cur;
cur->_parent=parent;
}
else if(parent->_key<key)
{
parent->_right=cur;
cur->_parent=parent;
}
//更新平衡因子
//不平衡旋转
while(parent)
{
if(cur==parent->_right)
{
parent->bf++;
}
else
{
parent->bf--;
}
if(parent->bf==0)
{
break;
}
else if(parent->bf==1||parent->bf==-1)
{
cur=parent;
parent=cur->_parent;
}
else// bf==2 、-2
{
//旋转
if(parent->bf==-2)
{
if(cur->bf==-1)
{
RotateR(parent);
}
else
{
RotateLR(parent);
}
break;
}
else
{
if(cur->bf==1)
{
RotateL(parent);
}
else
{
RotateRL(parent);
}
break;
}
}

}
return true;
}
bool Find(K key)
{

}
bool Remove()
{}
void InOrder()
{
_InOrder(_root);
}
bool IsBalance()
{
return _IsBalance(_root);
}
private:
bool Height(Node* root)
{
if(root==NULL)
{
return 0;
}
int left_height=Height(root->_left);
int right_height=Height(root->_right);
return left_height ? right_height+1 : left_height+1;
}
bool _IsBalance(Node* root)
{
if(root==NULL)
{
return true;
}
int left=Height(root->_left);
int right=Height(root->_right);
return abs(left-right)<2 && _IsBalance(root->_left)&&_IsBalance(root->_right);
}
void _InOrder(Node* root)
{
if(root==NULL)
{
return;
}
_InOrder(root->_left);
cout<<root->_key<<endl;
_InOrder(root->_right);
}
void RotateR(Node* parent)
{
Node* subL=parent->_left;
Node* subLR=subL->_right;
Node* ppNode=parent->_parent;
subL->_right=parent;
parent->_parent=subL;
if(subLR)
{
subLR->_parent=parent;
}
parent->_left=subLR;
if(ppNode&&ppNode->_left==parent)
{
ppNode->_left=subL;

}
else if(ppNode&&ppNode->_right==parent)
{
ppNode->_right=subL;
}
subL->_parent=ppNode;
subL->bf=parent->bf=0;
if(ppNode==NULL)
{
_root=subL;
}
}
void RotateL(Node* parent)
{
Node* subR=parent->_right;
Node* subRL=subR->_left;
Node* ppNode=parent->_parent;
subR->_left=parent;
parent->_parent=subR;
if(subRL)
{
subRL->_parent=parent;
}
parent->_right=subRL;
if(ppNode&&ppNode->_left==parent)
{
ppNode->_left=subR;

}
else if(ppNode&&ppNode->_right==parent)
{
ppNode->_right=subR;
}
subR->_parent=ppNode;
subR->bf=parent->bf=0;
if(ppNode==NULL)
{
_root=subR;
}
}
void RotateLR(Node* parent)
{
Node* subL=parent->_left;
Node* subLR=subL->_right;
int bf=subLR->bf;
RotateL(parent->_left);
RotateR(parent);
if(bf==-1)
{
parent->bf=1;
subL->bf=0;
}
else if(bf==1)
{
parent->bf=0;
subL->bf=-1;
}
else
{
parent->bf=subL->bf=0;
}
subLR->bf=0;
}
void RotateRL(Node* parent)
{
Node* subR=parent->_right;
Node* subRL=subR->_left;
int bf=subRL->bf;
RotateR(parent->_right);
RotateL(parent);
if(bf==-1)
{
parent->bf=0;
subR->bf=1;
}
else if(bf==1)
{
parent->bf=-1;
subR->bf=0;
}
else
{
parent->bf=subR->bf=0;
}
subRL->bf=0;

}
private:
Node* _root;
};

#include "AVLTree.h"
int main()
{
//int a[]={16,3,7,11,9,26,18,14,15};
int a[]={4, 2, 6, 1, 3, 5, 15, 7, 16, 14};
AVLTree<int,int> t;
for(int i=0;i<sizeof(a)/sizeof(a[0]);i++)
{
t.Insert(a[i],i);
}
t.InOrder();
cout<<t.IsBalance()<<endl;
system("pause");
return 0;
}

五、结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: