AVL树

AVL树的特征

1 AVL树 仍然是 左 子 结点 小于 父 结点, 父 结点 小于 右 子 结点
2 AVL树 AVL 树( Adel' son- Vel' skii and Landis) 是一 种 特殊 类型 的 二 叉 树, 它的 每个 结点 都 保存 一份 额外 的 信息: 结点 的 平衡 因子。
3 AVL 树 需要 自我 调整, 使得 所有 结点 的 平衡 因子 保持 为+ 1、- 1 或 0。 当子 树 的 根 结点 平衡 因子 为+ 1 时, 它是 左 倾斜 的( left- heavy)。 当子 树 的 根 结点 平衡 因子 为- 1 时, 它是 右 倾斜 的
4 AVL 树( Adel' son- Vel' skii and Landis) 是一 种 特殊 类型 的 二 叉 树, 它的 每个 结点 都 保存 一份 额外 的 信息: 结点 的 平衡 因子。

avl树 是在二叉树的基础上对数据进行了特俗的处理,我们任然可以复用树的实现链表代码

list.h和list.c tree.c和tree.h请复用以前的代码

总的来说,其实以前的树的机构不变。在*data指针的数据里面新增了两个字段,一个是平衡参数,一个是是否隐藏,通过两个参数来实现平衡。

头文件

//
//  avltree.h
//  bsearchtree
//
//  Created by bikang on 16/9/27.
//  Copyright (c) 2016年 bikang. All rights reserved.
//

#ifndef __bsearchtree__avltree__
#define __bsearchtree__avltree__

#include "tree.h"

#define  AVL_LEFT_HEAVY 1
#define AVL_BLANCED 0
#define  AVL_RIGHT_HEAVY -1

typedef struct AvlNode_{
    void *data;
    int hidden;
    int factor;
}AvlNode;

typedef BitTree BisTree;

void bistree_init(BisTree *tree,int (*compare)(const void *k1,const void *k2),void (*destroy)(void *data));
void bistree_destroy(BisTree *tree);
int bistree_insert(BisTree *tree,const void *data);
int bistree_remove(BisTree *tree,const void *data);
int bistree_lookup(BisTree *tree,void **data);



#define bistree_size(tree) ((tree)->size)

#endif /* defined(__bsearchtree__avltree__) */

实现代码

//
//  avltree.c
//  bsearchtree
//
//  Created by bikang on 16/9/27.
//  Copyright (c) 2016年 bikang. All rights reserved.
//

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "avltree.h"

static void destroy_right(BisTree *tree,BitTreeNode *node);

//左边旋转-节点指针
static void rotate_left(BitTreeNode **node)
{
    BitTreeNode *left,*grandchild;
    left = bitree_left(*node);
    //左子树超重
    if((((AvlNode*)bitree_data(left))->factor) == AVL_LEFT_HEAVY){
        //处理Left left超重
        bitree_left(*node) = bitree_right(left);
        bitree_right(left) = *node;
        ((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
        ((AvlNode*)bitree_data(left))->factor = AVL_BLANCED;
        *node = left;
    }else{
        //处理left right超重
        grandchild = bitree_right(left);
        bitree_right(left) = bitree_left(grandchild);//step 1
        bitree_left(grandchild) = left;//step 2
        bitree_left(*node) = bitree_right(grandchild);//step 3
        bitree_right(grandchild) = *node;//step4

        //调整平衡参数
        switch (((AvlNode*)bitree_data(grandchild))->factor) {
            case AVL_LEFT_HEAVY:
                ((AvlNode*)bitree_data(*node))->factor = AVL_RIGHT_HEAVY;
                ((AvlNode*)bitree_data(left))->factor = AVL_BLANCED;
                break;
            case AVL_BLANCED:
                ((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
                ((AvlNode*)bitree_data(left))->factor = AVL_BLANCED;
                break;
            case AVL_RIGHT_HEAVY:
                ((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
                ((AvlNode*)bitree_data(left))->factor = AVL_LEFT_HEAVY;
                break;
        }
        ((AvlNode*)bitree_data(grandchild))->factor  = AVL_BLANCED;
        *node = grandchild;
    }
    return;
}


//类似左旋转,只是方向不一样
static void rotate_right(BitTreeNode **node){
    BitTreeNode *right,*grandchild;
    right = bitree_right(*node);

    if((((AvlNode*)bitree_data(right))->factor) == AVL_RIGHT_HEAVY){
        //处理RR的情况
        bitree_right(*node) = bitree_left(right);
        bitree_left(right) = *node;
        ((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
        ((AvlNode*)bitree_data(right))->factor = AVL_BLANCED;
        *node = right;
    }else{
        grandchild = bitree_left(right);
        bitree_left(right) = bitree_right(grandchild);//step1
        bitree_right(grandchild) = right;//step2
        bitree_right(*node) = bitree_left(grandchild);//step3
        bitree_left(grandchild) = *node;//step4

        //调整平衡参数
        switch (((AvlNode*)bitree_data(grandchild))->factor) {
            case AVL_LEFT_HEAVY:
                ((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
                ((AvlNode*)bitree_data(right))->factor = AVL_RIGHT_HEAVY;
                break;
            case AVL_BLANCED:
                ((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
                ((AvlNode*)bitree_data(right))->factor = AVL_BLANCED;
                break;
            case AVL_RIGHT_HEAVY:
                ((AvlNode*)bitree_data(*node))->factor = AVL_LEFT_HEAVY;
                ((AvlNode*)bitree_data(right))->factor = AVL_BLANCED;
                break;
        }

        ((AvlNode*)bitree_data(grandchild))->factor  = AVL_BLANCED;
        *node = grandchild;
    }
    return;
}


static void destroy_left(BisTree *tree, BitTreeNode *node){
    BitTreeNode **position;

    if(bitree_size(tree) == 0) return;

    if(node == NULL){
        position = &tree->root;
    }else{
        position = &node->left;
    }
    if (*position != NULL) {
        destroy_left(tree, *position);
        destroy_right(tree, *position);
        if(tree->destroy != NULL){
            tree->destroy((((AvlNode*)(*position)->data))->data);
        }
        free((*position)->data);
        free(*position);
        *position = NULL;
        tree->size--;
    }

    return;
}


static void destroy_right(BisTree *tree,BitTreeNode *node){
    BitTreeNode **position;

    if(bitree_size(tree) == 0) return;

    if(node == NULL){
        position = &tree->root;
    }else{
        position = &node->right;
    }
    if (*position != NULL) {
        destroy_left(tree, *position);
        destroy_right(tree, *position);
        if(tree->destroy != NULL){
            tree->destroy((((AvlNode*)(*position)->data))->data);
        }
        free((*position)->data);
        free(*position);
        *position = NULL;
        tree->size--;
    }
    return;
}


//插入数据,也是最关键的部分,每次插入都得平衡
static int insert(BisTree *tree,BitTreeNode **node,const void*data,int *balanced ){
    AvlNode *avl_data;
    int cmpval,retval;
    //printf("*data=%d",*(int*)data);
    if(bitree_is_eob(*node)){
        if((avl_data =(AvlNode *)malloc(sizeof(AvlNode))) == NULL) return -1;
        avl_data->factor = AVL_BLANCED;
        avl_data->hidden = 0;
        avl_data->data = (void*)data;
        return bitree_ins_left(tree, *node, avl_data);
    }else{

        cmpval = tree->compare(data,((AvlNode *)(bitree_data(*node)))->data);
        //printf("###node=%d,%d\n",*(int*)(((AvlNode*)bitree_data(*node))->data),cmpval);
        if(cmpval < 0){
            if(bitree_is_eob(bitree_left(*node))){
                if((avl_data =(AvlNode *)malloc(sizeof(AvlNode))) == NULL) return -1;

                avl_data->factor = AVL_BLANCED;
                avl_data->hidden = 0;
                avl_data->data = (void*)data;
                if(bitree_ins_left(tree, *node, avl_data) != 0) return -1;
                *balanced = 0;
            }else{
                //继续往左边寻找
                if((retval = insert(tree,&bitree_left(*node),data,balanced)) !=0){
                    return retval;
                }
            }
            //左子树非平衡的
            if(!(*balanced)){
                switch (((AvlNode*)bitree_data(*node))->factor) {
                    case AVL_LEFT_HEAVY:
                        rotate_left(node);
                        *balanced = 1;
                        break;
                    case AVL_BLANCED:
                        //如果左子树平衡,左边会重因为新插入元素
                        ((AvlNode*)bitree_data(*node))->factor = AVL_LEFT_HEAVY;
                        break;
                    case AVL_RIGHT_HEAVY:
                        ((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
                        *balanced = 1;
                        break;
                }
            }
        }else if (cmpval > 0){
            if(bitree_is_eob(bitree_right(*node))){

                if((avl_data =(AvlNode *)malloc(sizeof(AvlNode))) == NULL) return -1;

                avl_data->factor = AVL_BLANCED;
                avl_data->hidden = 0;
                avl_data->data = (void*)data;
                if(bitree_ins_right(tree, *node, avl_data) != 0) return -1;
                *balanced = 0;
            }else{
                if((retval = insert(tree,&bitree_right(*node),data,balanced)) !=0){
                    return retval;
                }
            }
            if(!(*balanced)){
                switch (((AvlNode*)bitree_data(*node))->factor)
                {
                    case AVL_LEFT_HEAVY:
                        ((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
                        *balanced = 1;
                        break;
                    case AVL_BLANCED:
                        ((AvlNode*)bitree_data(*node))->factor = AVL_RIGHT_HEAVY;
                        break;
                    case AVL_RIGHT_HEAVY:
                        rotate_right(node);
                        *balanced = 1;
                        break;
                }
            }
        }else{
            //数据已经存在
            if(!((AvlNode*)bitree_data(*node))->hidden){
                return 1;
            }else{
                //插入新的数据
                if(tree->destroy!= NULL){
                    tree->destroy(((AvlNode*)bitree_data(*node))->data);
                }
                ((AvlNode*)bitree_data(*node))->data = (void*)data;
                ((AvlNode*)bitree_data(*node))->hidden = 0;
                *balanced = 1;
            }
        }
    }
    return 0;
}


static int hide(BisTree *tree,BitTreeNode *node,const void *data){
    int cmpval,retval;

    if(bitree_is_eob(node)) return -1;

    cmpval = tree->compare(data,((AvlNode*)bitree_data(node))->data);
    if(cmpval < 0){
        retval = hide(tree,bitree_left(node),data);
    }else if(cmpval > 0){
        retval = hide(tree,bitree_right(node),data);
    }else{
        ((AvlNode*)bitree_data(node))->hidden = 1;
        retval = 0;
    }
    return retval;
}

static int lookup(BisTree *tree,BitTreeNode *node,const void **data){
    int cmpval,retval;
    if(bitree_is_eob(node)) return -1;
    cmpval = tree->compare(*data,((AvlNode*)bitree_data(node))->data);
    //printf("%d,%d,cmp=%d\n",**(int**)data,*(int*)((AvlNode*)bitree_data(node))->data,cmpval);
    if(cmpval < 0){
        retval = lookup(tree,bitree_left(node),data);
    }else if(cmpval > 0){
        retval = lookup(tree,bitree_right(node),data);
    }else{

        if(!((AvlNode*)bitree_data(node))->hidden){
            *data =((AvlNode*)bitree_data(node))->data;
            retval = 0;
        }else{
            return -1;
        }
    }
    return retval;
}

void bistree_init(BisTree *tree,int (*compare)(const void *k1,const void *k2),void (*destroy)(void *data)){
    bitree_init(tree, destroy);
    tree->compare = compare;
    return;
}
void bistree_destroy(BisTree *tree){
    destroy_left(tree, NULL);
    memset(tree,0,sizeof(BitTree));
    return ;
}
int bistree_insert(BisTree *tree,const void *data){
    int balance = 0;
    return insert(tree,&bitree_root(tree),data,&balance);
}
int bistree_remove(BisTree *tree,const void *data){
    return hide(tree,bitree_root(tree),data);
}
int bistree_lookup(BisTree *tree,void **data){
    return lookup(tree, bitree_root(tree),(const void**)data);
}














测试代码

//
//  main.c
//  bsearchtree
//
//  Created by bikang on 16/9/27.
//  Copyright (c) 2016年 bikang. All rights reserved.
//
//AVL树 仍然是 左 子 结点 小于 父 结点, 父 结点 小于 右 子 结点
//AVL树 AVL 树( Adel' son- Vel' skii and Landis) 是一 种 特殊 类型 的 二 叉 树, 它的 每个 结点 都 保存 一份 额外 的 信息: 结点 的 平衡 因子。
//时, AVL 树 需要 自我 调整, 使得 所有 结点 的 平衡 因子 保持 为+ 1、- 1 或 0。 当子 树 的 根 结点 平衡 因子 为+ 1 时, 它是 左 倾斜 的( left- heavy)。 当子 树 的 根 结点 平衡 因子 为- 1 时, 它是 右 倾斜 的
//AVL 树( Adel' son- Vel' skii and Landis) 是一 种 特殊 类型 的 二 叉 树, 它的 每个 结点 都 保存 一份 额外 的 信息: 结点 的 平衡 因子。



#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "tree.h"
#include "avltree.h"
//打印链表
void print_list_info(List *list);
//先序
int preorder_tree(const BitTreeNode *node,List *list);
//中序排序
int inorder_tree(const BitTreeNode *node,List *list);
//比较数据
int compare_int(const void *a,const void *b){
    int a1 = *(int*)a;
    int b1 = *(int*)b;
    //printf("compare a1=%d,b1=%d\n",a1,b1);
    if(a1 == b1){
       return 0;
    }else if(a1 > b1) {
        return 1;
    }else{
        return -1;
    }
}

void ttree();

int main(int argc, const char * argv[]) {
    ttree();
    return 0;
}
void ttree(){
    int ret_val;

    BisTree *tree = (BisTree*)malloc(sizeof(BisTree));
    bistree_init(tree, compare_int, free);

    List *list = (List *)malloc(sizeof(List));
    list_init(list, NULL);


    int bistree_insert(BisTree *tree,const void *data);
    int a1 = 46;int *p1 = (int *)malloc(sizeof(int));*p1 = a1;
    int a2 = 22;int *p2 = (int *)malloc(sizeof(int));*p2 = a2;
    int a3 = 15;int *p3 = (int *)malloc(sizeof(int));*p3 = a3;
    int a4 = 43;int *p4 = (int *)malloc(sizeof(int));*p4 = a4;
    int a5 = 75;int *p5 = (int *)malloc(sizeof(int));*p5 = a5;
    int a6 = 71;int *p6 = (int *)malloc(sizeof(int));*p6 = a6;
    int a7 = 48;int *p7 = (int *)malloc(sizeof(int));*p7 = a7;
    bistree_insert(tree, (void*)p1);

    //插入
    bistree_insert(tree, (void*)p2);
    bistree_insert(tree, (void*)p3);
    bistree_insert(tree, (void*)p4);
    bistree_insert(tree, (void*)p5);
    bistree_insert(tree, (void*)p6);
    bistree_insert(tree, (void*)p7);
    //查找
    void **data = (void**)malloc(sizeof(int));
    *data = p3;
    ret_val = bistree_lookup(tree, data);
    if(ret_val == 0){
        puts("find ok");
    }
    //删除
    bistree_remove(tree,p3);


    //inorder_tree(bitree_root(tree),list);
    //print_list_info(list);

    preorder_tree(bitree_root(tree),list);
    print_list_info(list);

    bistree_destroy(tree);
    list_destroy(list);
}

//中序遍历
int inorder_tree(const BitTreeNode *node,List *list){
    if(!bitree_is_eob(node)){
        if(!bitree_is_eob(bitree_left(node))){
            if(inorder_tree(bitree_left(node),list) != 0){
                return -1;
            }
        }
        if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0) return -1;
        if(!bitree_is_eob(bitree_right(node))){
            if(inorder_tree(bitree_right(node),list) != 0){
                return -1;
            }
        }
    }
    return 0;
}

//先序遍历
int preorder_tree(const BitTreeNode *node,List *list){
    if(!bitree_is_eob(node)){
        if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0) return -1;
        if(!bitree_is_eob(bitree_left(node))){
            if(preorder_tree(bitree_left(node),list) != 0){
                return -1;
            }
        }
        if(!bitree_is_eob(bitree_right(node))){
            if(preorder_tree(bitree_right(node),list) != 0){
                return -1;
            }
        }
    }
    return 0;
}

//打印一个列表
void print_list_info(List *list){
    if(list_size(list) == 0){
        printf("empty list\n");
        return;
    }

    ListElmt *pl;
    pl = list_head(list);
    int i;
    printf("\n#########start#############\n");
    for(i=0;i<list_size(list);i++){
        printf("data=%d ",*(int*)(((AvlNode*)list_data(pl))->data));
        printf("hiden=%d ",(((AvlNode*)list_data(pl))->hidden));
        printf("factor=%d ",(((AvlNode*)list_data(pl))->factor));
        printf("\n");
        pl = pl->next;
    }
    printf("\n#########end#############\n");
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值