C 算法精介----二叉搜索树-->AVL树->分析与实现








//
//  Bistree.h
//  Algorithms&Data_structures
//
//  Created by TTc on 15-2-4.
//  Copyright (c) 2015年 TTc. All rights reserved.
//

#ifndef __Algorithms_Data_structures__Bistree__
#define __Algorithms_Data_structures__Bistree__

#include 
#include "BiTree.h"
/*定义平衡因子为AVL树*/
#define  AVL_LFT_HEAVY               1
#define  AVL_BALANCED                0
#define  AVL_RGT_HEAVY             -1

/*定义AVL树的节点*/
typedef struct AvlNode_{
    void *data;
    int hidden;
    int factor;//平衡因子
}AvlNode;

typedef BiTree BisTree;

/*函数接口*/
void bistree_init (BisTree *tree, int (*compare)(const void *key1,const void
                                                 *key2),void (*destroy)(void *data));
void bistree_destory(BisTree *tree);

int bistree_insert(BisTree *tree,const void *data);

int bistree_remove(BisTree * tree, const void * data);


int bistree_lookup(const BisTree *tree,void **data);

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



#endif /* defined(__Algorithms_Data_structures__Bistree__) */

//
//  Bistree.c
//  Algorithms&Data_structures
//
//  Created by TTc on 15-2-4.
//  Copyright (c) 2015年 TTc. All rights reserved.
//

#include "Bistree.h"
#include 
#include 

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

/*      AVL 左旋操作     */
static void
rotate_left(BiTreeNode **node){
    
    BiTreeNode *left , *grandchild;
    left = bitree_right(*node);
    
    if (((AvlNode *)bitree_data(left)) ->factor == AVL_RGT_HEAVY){
        /* RR */
        bitree_right(*node) = bitree_left(left);
        bitree_left(left) = *node;
        ((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED;
        ((AvlNode *)bitree_data(left)) ->factor = AVL_BALANCED;
        *node = left;
    } else { /*RL*/
        grandchild  = bitree_right(left);
        bitree_right(left) = bitree_left(grandchild);
        bitree_left(grandchild) = left;
        bitree_left(*node) = bitree_right(grandchild);
        bitree_right(grandchild) = *node;
        
        switch (((AvlNode *)bitree_data(grandchild)) ->factor){
            case AVL_LFT_HEAVY:
                ((AvlNode *)bitree_data(*node)) ->factor = AVL_RGT_HEAVY;
                ((AvlNode *)bitree_data(left)) ->factor = AVL_BALANCED;
                break;
                
            case AVL_BALANCED:
                ((AvlNode *)bitree_data(*node)) ->factor = AVL_BALANCED;
                ((AvlNode *)bitree_data(left)) ->factor = AVL_BALANCED;
                break;
                
            case AVL_RGT_HEAVY:
                ((AvlNode *)bitree_data(*node)) ->factor = AVL_BALANCED;
                ((AvlNode *)bitree_data(left)) ->factor = AVL_LFT_HEAVY;
                break;
        }
        ((AvlNode *)bitree_data(grandchild)) ->factor = AVL_BALANCED;
        *node = grandchild;
    }
    return;
}

/*      AVL 右旋操作        */
static void
rotata_right(BiTreeNode **node){
    BiTreeNode *right , *grandchild;
    right = bitree_left(*node);
    
    if (((AvlNode *)bitree_data(right)) ->factor == AVL_LFT_HEAVY){
        /* LL */
        bitree_right(*node) = bitree_left(right);
        bitree_left(right) = *node;
        ((AvlNode *)bitree_data(*node))->factor = AVL_BALANCED;
        ((AvlNode *)bitree_data(right)) ->factor = AVL_BALANCED;
        *node = right;
        
    } else { /*LR*/
        grandchild = bitree_left(right);
        bitree_left(right) = bitree_right(grandchild);
        bitree_right(grandchild) = right;
        bitree_right(*node) = bitree_left(grandchild);
        bitree_left(grandchild) = *node;
        
        switch (((AvlNode *)bitree_data(grandchild)) ->factor){
            case AVL_LFT_HEAVY:
                ((AvlNode *)bitree_data(*node)) ->factor = AVL_BALANCED;
                ((AvlNode *)bitree_data(right)) ->factor = AVL_RGT_HEAVY;
                break;
                
            case AVL_BALANCED:
                ((AvlNode *)bitree_data(*node)) ->factor = AVL_BALANCED;
                ((AvlNode *)bitree_data(right)) ->factor = AVL_BALANCED;
                break;
                
            case AVL_RGT_HEAVY:
                ((AvlNode *)bitree_data(*node)) ->factor = AVL_LFT_HEAVY;
                ((AvlNode *)bitree_data(right)) ->factor = AVL_BALANCED;
                break;
        }
        ((AvlNode *)bitree_data(grandchild)) ->factor = AVL_BALANCED;
        *node = grandchild;
    }
    return;
}


/*删除当前节点的左子树
 * 如过参数node为NULL,表示删除所有节点
 */
static void
destroy_left (BisTree * tree, BiTreeNode * node){
    BiTreeNode ** position;
    /*当树为空时,直接返回*/
    if (bistree_size(tree) == 0){
        return;
    }
    /*当删除节点为NULL时,当前位置指向树根
     否则,指向当前节点的左子树*/
    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 ;
}

/*删除节点的右子树
 *如果节点为NULL,删除整个树
 */
static void
destroy_right(BisTree * tree, BiTreeNode * node){
    BiTreeNode ** position;
    /*当树为空时,直接返回*/
    if (bistree_size(tree) == 0){
        return;
    }
    /*当删除节点为NULL时,当前位置指向树根
     否则,指向当前节点的左子树*/
    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,BiTreeNode **node,const void *data,int *balanced){
    
    AvlNode *avl_data;
    int cmpval,retval;
    /*   Insert the data  into the  tree   */
    if (bitree_is_eob(*node)){/*插入到根节点*/
        /*申请空间,并赋值*/
        if ((avl_data = (AvlNode *)malloc(sizeof(AvlNode))) == NULL)
            return -1;
        avl_data ->factor = AVL_BALANCED;
        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);
        if (cmpval < 0){
            /*插入数值小于节点数值时,插入左子树*/
            if (bitree_is_eob(bitree_left(*node))){
                /*当插入节点左子树为空时,直接插入并且树平衡*/
                if ((avl_data = (AvlNode *) malloc(sizeof(AvlNode))) == NULL)
                    return -1;
                avl_data ->factor = AVL_BALANCED;
                avl_data ->hidden = 0;
                avl_data -> data = (void *) data;
                *balanced = 0;
                return bitree_ins_left(tree, * node, avl_data);
            } else { /*当不为空时,继续判断*/
                if ((retval = insert( tree, &bitree_left(*node), data, balanced)) != 0)
                    return retval;
            }
            
            /*确保树的平衡*/
            if (!(*balanced)){
                switch (((AvlNode *)bitree_data(*node))->factor){
                    case AVL_LFT_HEAVY:
                        rotata_right(node);
                        *balanced = 1;
                        break;
                        
                    case AVL_BALANCED:
                        ((AvlNode*)bitree_data(*node)) -> factor = AVL_LFT_HEAVY;
                        break;
                        
                    case AVL_RGT_HEAVY:
                        ((AvlNode*)bitree_data(*node)) -> factor = AVL_BALANCED;
                        *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_BALANCED;
                avl_data ->hidden = 0;
                avl_data -> data = (void *) data;
                *balanced = 0;
                return bitree_ins_right(tree, * node, avl_data);
            } else {/*节点不为空时,继续插入*/
                if ((retval = insert( tree, &bitree_right(*node), data, balanced)) != 0)
                    return retval;
            }
            
            /*确保树的平衡*/
            if (!(*balanced)){
                
                switch (((AvlNode *)bitree_data(*node))->factor){
                    case AVL_RGT_HEAVY:
                        rotata_right(node);
                        *balanced = 1;
                        break;
                        
                    case AVL_BALANCED:
                        ((AvlNode*)bitree_data(*node))->factor = AVL_RGT_HEAVY;
                        break;
                        
                    case AVL_LFT_HEAVY:
                        ((AvlNode*)bitree_data(*node))->factor = AVL_BALANCED;
                        *balanced = 1;
                        break;
                }
            }
            
        } else {
            /*cmpval = 0*/
            /*插入数据相同*/
            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, BiTreeNode *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;
}

/*查找数据*/
int
look_up(BisTree *tree, BiTreeNode *node, 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 = look_up(tree, bitree_left(node),data);
    } else if (cmpval > 0){
        retval = look_up( 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;
}



/*初始化AVL*/
//O(1)
void
bistree_init(BisTree * tree, int(* compare)(const void * key1, const void * key2), void(* destroy)(void * data)){
    bitree_init(tree, destroy);
    tree->compare = compare;
}

//O(n)
void
bistree_destory(BisTree *tree){
    /*删除所有节点*/
    destroy_left( tree, NULL);
    memset(tree,0,sizeof(BisTree));
}

/*插入数据
 *  返回值:
 * 0: 成功
 *  1: 插入数据已经存在树中
 *  -1: 失败
 *O(lg n)
 */
int
bistree_insert(BisTree *tree,const void *data){
    /*balance 作用是设置一个标志位用来对二叉树的
     *左右旋操作及设置factor的数值
     * 0:表示不平衡,需要重新设置
     * 1:则正好相反。
     */
    int balance = 0;
    return insert(tree,&bitree_root(tree),data,&balance);
}

/*删除数据
 * 原则上并未删除这个节点,只是将节点标志设置
 * 为隐藏。
 *  返回值:
 * 0: 成功
 * -1: 失败
 *O(lg n)
 */
int
bistree_remove(BisTree * tree, const void * data){
    return hide (tree,bitree_root(tree),data);
}

/*查询参数tree所指向的二叉搜索树重是否存在数据同参数data相吻合的节点
 * 如果查找成功,则函数返回后参数data指向查找到的节点的数据。
 *  返回值:
 * 0: 成功
 * -1: 失败
 *O(lg n)
 */
int
bistree_lookup(const BisTree *tree,void **data){

    return look_up(tree, NULL, data);
}





你可能感兴趣的:(Algorithms)