AVL树

AVL树是带有平衡条件的二叉查找树。主要的一种AVL树是这样一种树:它带有平衡条件,它的每个节点的左子树和右子树的的高度最多相差1。下面左边的树是AVL树,右边不是,因为7的左右子树的高度相差大于1。

当一个节点插入破坏了某个点的平衡。我们假设这个点是a。可能有下面有下面四种情况破坏了平衡。
1.对a的左儿子的左子树进行一次插入。
2.对a的左儿子的右子树进行一次插入。
3.对a的右儿子的左子树进行一次插入。
4.对a的右儿子的右子树进行一次插入。
情形1和4是关于a点的镜像对称,而2和3是关于a点的镜像对称。
1.单旋转
针对情形1和4。采用单旋转可以重新调整平衡。
情形1:

为使左边的树恢复平衡,我们把x上移一层,把z下移一层。重新安排k1和k2得到右边的图。相当于把k1几点往上提,这时k2变成了k1的右子树。原来的k1的右子树变成了k2的左子树。
2.双旋转
针对情形2和3,单旋转无法实现树的平衡。必须旋转两次。

上面的图在k3点经过一次左旋转(将k2往上提),得到下面的图。

上面的图在k1点经过右旋转可以得到下面的图。这就是一个AVL树了。

3 AVL树的实现
下面是AVL树的实现,需要注意的时,树的结构有一个字段is_delete来标记节点是否逻辑删除,也就是懒删除。
3.1 头文件
//
//  AVLTree.h
//  AVLTree
//
//  Created by Wuyixin on 2017/5/28.
//  Copyright © 2017年 Coding365. All rights reserved.
//

#ifndef AVLTree_h
#define AVLTree_h

#include <stdio.h>
#include <stdlib.h>

#define MAX(a,b) ((a)>(b)?(a):(b))

typedef int ElemType;

struct AVLNODE;
typedef struct AVLNODE AvlNode;
typedef struct AVLNODE *Position;
typedef struct AVLNODE *AvlTree;

/* 置为空树 */
AvlTree make_empty(AvlTree t);
/* 查找节点 */
Position find(ElemType x,AvlTree t);
/* 查找最小节点 */
Position find_min(AvlTree t);
/* 查找最大节点 */
Position find_max(AvlTree t);
/* 插入节点 */
AvlTree insert(ElemType x,AvlTree t);
/* 删除节点--lazy删除 */
void delete_lazy(ElemType x,AvlTree t);
/* 树的遍历--中序遍历 */
void print_tree(AvlTree t);

struct AVLNODE
{
    ElemType elem;
    AvlTree left;
    AvlTree right;
    int height;
    int is_delete;
};
#endif /* AVLTree_h */


3.2 实现文件
//
//  AVLTree.c
//  AVLTree
//
//  Created by Wuyixin on 2017/5/28.
//  Copyright © 2017年 Coding365. All rights reserved.
//

#include "AVLTree.h"

static int height(Position p){
    if (p == NULL)
        return -1;
    else
        return p->height;
}
/* 左旋转 */
static Position single_rotate_left(Position k2);
/* 右旋转 */
static Position single_rotate_right(Position k2);
/* 右-左旋转 */
static Position double_rotate_left(Position k3);
/* 左-右旋转 */
static Position double_rotate_right(Position k3);


AvlTree make_empty(AvlTree t){
    if (t != NULL){
        make_empty(t->left);
        make_empty(t->right);
        free(t);
    }
    return NULL;
}
Position find(ElemType x,AvlTree t){
    if (t == NULL)
        return NULL;
    if (x < t->elem)
        return find(x, t->left);
    else if(x > t->elem)
        return find(x, t->right);
    else
        return t;
}
Position find_min(AvlTree t){
    if (t == NULL)
        return NULL;
    else if(t->left == NULL)
        return t;
    else
        return find_min(t->left);
    
}
Position find_max(AvlTree t){
    if (t == NULL)
        return NULL;
    else if(t->right == NULL)
        return t;
    else
        return find_max(t->right);
}


static Position single_rotate_left(Position k2){
    Position k1;
    k1 = k2->left;
    
    k2->left = k1->right;
    k1->right = k2;
    
    k1->height = MAX(height(k1->left), height(k2->right)) + 1;
    k2->height = MAX(height(k2->left), height(k2->right)) + 1;
    
    return k1;
}


static Position single_rotate_right(Position k2){
    Position k1;
    k1 = k2->right;
    
    k2->right = k1->left;
    k1->left = k2;
    
    k1->height = MAX(height(k1->left), height(k2->right)) + 1;
    k2->height = MAX(height(k2->left), height(k2->right)) + 1;
    
    return k1;
}

static Position double_rotate_left(Position k3){
    
    /* k1与k2之间 */
    k3->left = single_rotate_right(k3->left);
    /* k2与k3之间*/
    return single_rotate_left(k3);
}

static Position double_rotate_right(Position k3){
    /* k1与k2之间 */
    k3->right = single_rotate_left(k3->right);
    /* k2与k3之间*/
    return single_rotate_right(k3);
}


AvlTree insert(ElemType x,AvlTree t){
    if (t == NULL) {
        t = (AvlTree)malloc(sizeof(AvlNode));
        if (t == NULL) exit(EXIT_FAILURE);
        t->left = t->right = NULL;
        t->elem = x;
        t->is_delete = 0;
    }else if(x < t->elem){
        t->left = insert(x, t->left);
        if (height(t->left) - height(t->right) > 1){
            if (x < t->left->elem)
                t = single_rotate_left(t);
            else
                t = double_rotate_left(t);
        }
    }else if(x > t->elem){
        t->right = insert(x, t->right);
        if (height(t->right) - height(t->left) > 1){
            if (x > t->right->elem)
                t = single_rotate_right(t);
            else
                t = double_rotate_right(t);
        }
    }else
        /* 如果x在树中,看它是否被标记删除 */
        t->is_delete = 0;
    
    
    
    t->height = MAX(height(t->left), height(t->right)) + 1;
    return t;
}

void print_tree(AvlTree t)
{
    if(t != NULL && !t->is_delete){
        print_tree(t->left);
        printf("%d ",t->elem);
        print_tree(t->right);

    }
}

void delete_lazy(ElemType x,AvlTree t){
    Position p = find(x, t);
    if (p != NULL) p->is_delete = 1;
    
}








3.3 调用
//
//  main.c
//  AVLTree
//
//  Created by Wuyixin on 2017/5/28.
//  Copyright © 2017年 Coding365. All rights reserved.
//

#include <stdio.h>
#include "AVLTree.h"
int main(int argc, const char * argv[]) {
    
    AvlTree t = NULL;
    t = insert(1, t);
    t = insert(2, t);
    t = insert(3, t);
    t = insert(4, t);
    t = insert(5, t);
    t = insert(6, t);
    t = insert(7, t);
    t = insert(8, t);
    t = insert(9, t);
    t = insert(10, t);
    print_tree(t);
    delete_lazy(5, t);
    printf("\n");
    print_tree(t);
    
    return 0;
}





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值