AVL树
昨天谈了堆,那么今天来谈下AVL树,它也是一种二叉树,而且是平衡的二叉树,对于点的插入和删除以及查找的复杂度都是 O ( l o g n ) O(logn) O(logn),可以说非常高效有用。
简介:
https://baike.baidu.com/item/AVL树/10986648
AVL的简单介绍可以参考百度,也可以自己找本数据结构的书来看,一般里面都会提到这个数据结构。这个数据的出现是为了弥补不平衡二叉树。我们在维护一个可以查询的二叉树,把小于根结点的值插入到二叉树的左边,大于根结点的值插入到二叉树的右边。但这样很容易导致最后构造出来的树不平衡,为了弥补这一缺陷,引入了AVL树的概念。AVL树能够保证平衡是因为每当出现不平衡时,它可以通过一种旋转的操作来使得树重新平衡。旋转有四种操作,左左旋转,左右旋转,右右旋转,右左旋转。四种操作分别对应四种不平衡的状态:
(1) 左左旋转
当以
i
i
i为根结点的左子树的高度与右子树高度差大于1时,且
i
i
i的左子树的左子树的高度大于其右子树高度,此时出现不平衡,需左左旋转.
(2) 左右旋转
当以
i
i
i为根结点的左子树的高度与右子树高度差大于1时,且
i
i
i的左子树的右子树的高度大于其左子树高度,此时出现不平衡,需左右旋转.
(3) 右右旋转
当以
i
i
i为根结点的右子树的高度与左子树高度差大于1时,且
i
i
i的右子树的右子树的高度大于其左子树高度,此时出现不平衡,需右右旋转.
(4) 右左旋转
当以
i
i
i为根结点的右子树的高度与左子树高度差大于1时,且
i
i
i的右子树的左子树的高度大于其右子树高度,此时出现不平衡,需右左旋转.
具体的操作的话,由于我比较懒,附上一篇微信的文章,里面把操作的过程写得很详细,可以参考下:
http://mp.weixin.qq.com/s?__biz=MzU0ODczMTEwOQ==&mid=2247486725&idx=1&sn=cbf6f47820c820bf44f7a236d70a5c56&chksm=fbbbec8fcccc65994d227c410b63324d95387b663bac5f887b37d68bafbf2c2eb770d010ac13&mpshare=1&scene=23&srcid=03067D32oynD4mI1lNeixYCR#rd
C++代码实现
#include<bits/stdc++.h>
using namespace std;
class AVL{
private:
Node *header;
Node *LL_rotate(Node *root); //左左旋转;
Node *RR_rotate(Node *root); //右右旋转;
Node *LR_rotate(Node *root); //左右旋转;
Node *RL_rotate(Node *root); //右左旋转;
void destroy(Node *node); //删除整棵树;
int get_height(Node *node); //获取结点的高度;
int get_balance(Node *node); //获取结点的平衡;
Node *insert_real(int key,Node *node); //插入结点;
Node *find_real(int key,Node *node); //查找结点;
Node *erase_real(int key,Node *node); //删除结点;
void print_real(Node *node); //按顺序输出整棵树;
public:
AVL();
~AVL();
void insert(int key);
Node* find(int key);
void erase(int key);
void print();
};
int AVL::get_height(Node *node){
if(node==nullptr){
return 0;
}
return node->height;
}
int AVL::get_balance(Node *node){ //返回结点的平衡差;
if(node==nullptr){
return 0;
}
return get_height(node->left)-get_height(node->right); //左子树高度减去右子树高度;
}
Node *AVL::LL_rotate(Node *root){ //左左旋转;
Node *new_root=root->left; //新的根为原根的左子树;
root->left=new_root->right;
new_root->right=root;
root->height=max(get_height(root->left),get_height(root->right))+1;
new_root->height=max(get_height(new_root->left),get_height(new_root->right))+1;
return new_root;
}
Node *AVL::RR_rotate(Node *root){ //右右旋转;
Node *new_root=root->right; //新的根为原根的右子树;
root->right=new_root->left;
new_root->left=root;
root->height=max(get_height(root->left),get_height(root->right))+1;
new_root->height=max(get_height(new_root->left),get_height(new_root->right))+1;
return new_root;
}
Node *AVL::LR_rotate(Node *root){ //左右旋转;
Node *new_root=root->left;
root->left=RR_rotate(new_root); //先右右旋转,再左左旋转;
return LL_rotate(root);
}
Node *AVL::RL_rotate(Node *root){ //右左旋转;
Node *new_root=root->right;
root->right=LL_rotate(new_root); //先左左旋装,再右右旋转;
return RR_rotate(root);
}
void AVL::destroy(Node *node){ //删除整棵树;
if(node==nullptr){
return;
}
//后序遍历删除整棵树;
destroy(node->left);
destroy(node->right);
delete node;
}
Node *AVL::insert_real(int key,Node *node){ //插入结点;
if(node==nullptr){
return new Node(key);
}
if(key<node->key){ //小于等于结点值的往左走;
node->left=insert_real(key,node->left);
}else if(key>node->key){ //大于等于结点值的往右走;
node->right=insert_real(key,node->right);
}else{ //相等时不插入;
return node;
}
node->height=max(get_height(node->left),get_height(node->right))+1;
int balance=get_balance(node); //左子树的高度减去右子树的高度;
if(balance>1&&get_balance(node->left)>0){ //左左失衡;
return LL_rotate(node);
}else if(balance>1&&get_balance(node->left)<0){ //左右失衡;
return LR_rotate(node);
}else if(balance<-1&&get_balance(node->right)<0){ //右右失衡;
return RR_rotate(node);
}else if(balance<-1&&get_balance(node->right)>0){ //右左失衡;
return RL_rotate(node);
}
return node;
}
Node *AVL::erase_real(int key,Node *node){ //删除结点;
if(node==nullptr){
return node;
}
if(key<node->key){
node->left=erase_real(key,node->left);
}else if(key>node->key){
node->right=erase_real(key,node->right);
}else{
if(node->left&&node->right){ //左子树右子树都存在;
Node *tmp=node->right; //找到右子树的最左边;
while(tmp->left){
tmp=tmp->left;
}
node->key=tmp->key;
node->right=erase_real(tmp->key,node->right);
}else{ //左右子树有一个不在;
Node *tmp=node;
node=node->left?node->left:node->right;
delete tmp;
if(node==nullptr){
return nullptr;
}
}
}
node->height=max(get_height(node->left),get_height(node->right))+1;
int balance=get_balance(node);
if(balance>1&&get_balance(node->left)>=0){ //左左失衡;
return LL_rotate(node);
}else if(balance>1&&get_balance(node->left)<0){ //左右失衡;
return LR_rotate(node);
}else if(balance<-1&&get_balance(node->right)<=0){ //右右失衡;
return RR_rotate(node);
}else if(balance<-1&&get_balance(node->right)>0){ //右左失衡;
return RL_rotate(node);
}
return node;
}
Node *AVL::find_real(int key,Node *node){ //查找结点;
if(node==nullptr){
return nullptr;
}
if(key<node->key){
return find_real(key,node->left);
}else if(key>node->key){
return find_real(key,node->right);
}
return node;
}
void AVL::print_real(Node *node){ //中序遍历输出整棵树(从小到大);
if(node==nullptr){
return;
}
print_real(node->left); //访问左子树;
cout<<node->key<<endl; //打印结点的值;
print_real(node->right); //访问右子树;
}
AVL::AVL(){ //创建头结点;
header=new Node(0);
}
AVL::~AVL(){ //释放内存;
destroy(header->left);
delete header;
header=nullptr;
}
//公共函数给类外部调用;
void AVL::insert(int key){ //插入key值;
header->left=insert_real(key,header->left);
}
void AVL::erase(int key){ //删除key值;
header->left=erase_real(key,header->left);
}
Node *AVL::find(int key){ //查找值;
return find_real(key,header->left);
}
void AVL::print(){ //打印整棵树;
print_real(header->left);
}
int main() //AVL类测试;
{
AVL tree;
for(int i=1;i<=100;i++){
tree.insert(i);
}
tree.erase(100);
tree.erase(1);
tree.print();
return 0;
}
新的开始,每天都要快乐哈!