zoukankan      html  css  js  c++  java
  • [算法] avl树实现

    大二的时候数据结构课死活没看懂的一个东东,看了2小时,敲了2小时,调了2小时。。。

    平衡树某一节点的左右子树高度相差大于1的时候即需要调整,调整可分为四中情况 ll,rr,lr,rl其中lr,rl是由不同顺序的ll,rr来实现的,代码比想象的简短。

    一棵平衡的树只有在插入和删除节点的时候,才会变的不平衡,所以掌握好时机,判断平衡是否破坏及不平衡的种类,再纠正即可

    代码如下。。

    avl.h

    struct AVLNode {
        struct AVLNode *left;
        struct AVLNode *right;
        int data;
        int height;
    };
    
    static const int AVL_STATUS_OK = 0;
    static const int AVL_STATUS_FOUNDED = 1;
    static const int AVL_STATUS_NOTFOUNDED = 2;
    static const int AVL_STATUS_FAILED = -1;
    
    int avl_insert(struct AVLNode **root, int data);
    int avl_find(struct AVLNode *root, int data);
    int avl_del(struct AVLNode **root, int data);
    int avl_del_tree(struct AVLNode *root);
    void print_avl_tree(struct AVLNode *root);
    int _get_height(struct AVLNode *node);
    int _max(int a, int b);
    void _single_rotate_left(struct AVLNode **node);
    void _single_rotate_right(struct AVLNode **node);
    void _double_rotate_left_right(struct AVLNode **node);
    void _double_rotate_right_left(struct AVLNode **node);
    

     

    avl.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    #include "avl.h"
    
    int avl_insert(struct AVLNode **ptr_root, int data) {
        int ret;
        if(NULL == *ptr_root) {
            *ptr_root = malloc(sizeof(struct AVLNode));
            if(NULL == *ptr_root) {
                return AVL_STATUS_FAILED;
            }
            (*ptr_root)->data = data;
            (*ptr_root)->left = NULL;
            (*ptr_root)->right = NULL;
            (*ptr_root)->height = 0;
            return AVL_STATUS_OK;
        }
    
        if(data == (*ptr_root)->data) {
            return AVL_STATUS_OK;
        }
        else if(data < (*ptr_root)->data) {
            ret = avl_insert(&((*ptr_root)->left), data);
            if(_get_height((*ptr_root)->left) - _get_height((*ptr_root)->right) > 1){
                if(data < (*ptr_root)->left->data){
                    _single_rotate_left(ptr_root);
                }
                else {
                    _double_rotate_left_right(ptr_root);
                }
            }
        }
        else {
            ret = avl_insert(&((*ptr_root)->right), data);
            if(_get_height((*ptr_root)->right) - _get_height((*ptr_root)->left) > 1){
                if(data > (*ptr_root)->right->data) {
                    _single_rotate_right(ptr_root);
                }
                else {
                    _double_rotate_right_left(ptr_root);
                }
            }
        }
        (*ptr_root)->height = _max(_get_height((*ptr_root)->left), _get_height((*ptr_root)->right)) + 1;
        return ret;
    }
    
    int avl_find(struct AVLNode *root, int data) {
        if(NULL == root) {
            return AVL_STATUS_NOTFOUNDED;
        }
        if(data == root->data) {
            return AVL_STATUS_FOUNDED;
        }
        if(data < root->data) {
            return avl_find(root->left, data);
        }
        else {
            return avl_find(root->right, data);
        }
    }
    
    int avl_del(struct AVLNode **root, int data) {
        struct AVLNode *t;
        if(*root == NULL) {
            return AVL_STATUS_OK;
        }
        if(data < (*root)->data) {
            avl_del(&((*root)->left), data);
            if(_get_height((*root)->right) - _get_height((*root)->left) > 1){
                if((*root)->right->left != NULL && (_get_height((*root)->right->left) > _get_height((*root)->right->right))) {
                    _double_rotate_right_left(root);
                }
                else {
                    _single_rotate_right(root);
                }
            }
        }
        else if(data > (*root)->data) {
            avl_del(&((*root)->right), data);
            if(_get_height((*root)->left) - _get_height((*root)->right) > 1){
                if((*root)->left->right != NULL && (_get_height((*root)->left->right) > _get_height((*root)->left->left))) {
                    _double_rotate_left_right(root);
                }
                else {
                    _single_rotate_left(root);
                }
            }
        }
        else {
            if(NULL != (*root)->left && NULL != (*root)->right) {
                t = (*root) -> right;
                while(t->left != NULL) {
                    t = t->left;
                }
                (*root) -> data = t->data;
                avl_del(&((*root)->right), t->data);
                if(_get_height((*root)->left) - _get_height((*root)->right) > 1){
                if((*root)->left->right != NULL && (_get_height((*root)->left->right) > _get_height((*root)->left->left))) {
                    _double_rotate_left_right(root);
                }
                else {
                    _single_rotate_left(root);
                }
            }
            }
            else {
                t = *root;
                if((*root)->left == NULL) {
                    *root = (*root) -> right;
                }
                else if((*root)->right == NULL) {
                    *root = (*root) -> left;
                }
                free(t);
            }
        }
        return AVL_STATUS_OK;
    }
    
    int avl_del_tree(struct AVLNode *root) {
        if(NULL == root) {
            return AVL_STATUS_OK;
        }
        avl_del_tree(root->left);
        avl_del_tree(root->right);
        free(root);
        return AVL_STATUS_OK;
    }
    
    int _get_height(struct AVLNode *node) {
        if(NULL == node){
            return -1;
        }
        else{
            return node->height;
        }
    }
    
    int _max(int a, int b) {
        return a > b ? a:b;
    }
    
    void _single_rotate_left(struct AVLNode **node) {
        struct AVLNode* root = *node;
        *node = root->left;
        root->left = (*node)->right;
        (*node)->right = root;
        root->height = _max(_get_height(root->left), _get_height(root->right)) + 1;
        (*node)->height = _max(_get_height((*node)->left), _get_height((*node)->right)) + 1;
    }
    
    void _single_rotate_right(struct AVLNode **node) {
        struct AVLNode* root = *node;
        *node = root->right;
        root->right = (*node)->left;
        (*node)->left = root;
        root->height = _max(_get_height(root->left), _get_height(root->right)) + 1;
        (*node)->height = _max(_get_height((*node)->left), _get_height((*node)->right)) + 1;
    }
    
    void _double_rotate_left_right(struct AVLNode **node) {
        struct AVLNode* root = *node;
        _single_rotate_right(&(root->left));
        _single_rotate_left(node);
    }
    
    void _double_rotate_right_left(struct AVLNode **node) {
        struct AVLNode* root = *node;
        _single_rotate_left(&(root->right));
        _single_rotate_right(node);
    }
    
    void print_avl_tree(struct AVLNode *node) {
        if(NULL == node) {
            return;
        }
        print_avl_tree(node->left);
        printf("%d	%d
    ", node->data, node->height);
        print_avl_tree(node->right);
    }
    

      

    main.c

    #include <stdio.h>
    
    #include "avl.h"
    
    int main() {
        struct AVLNode *root = NULL;
        int ret = avl_insert(&root, 7);
        printf("hello, world
    ");
        printf("root:address %ld
    ", (long)root);
        printf("after:%d
    ", 7);
        print_avl_tree(root);
        avl_insert(&root, 6);
        printf("after:%d
    ", 6);
        print_avl_tree(root);
        avl_insert(&root, 5);
        printf("after:%d
    ", 5);
        print_avl_tree(root);
        avl_insert(&root, 7);
        printf("after:%d
    ", 7);
        print_avl_tree(root);
        avl_insert(&root, 1);
        printf("after:%d
    ", 1);
        print_avl_tree(root);
        avl_insert(&root, 0);
        printf("after:%d
    ", 0);
        print_avl_tree(root);
        avl_insert(&root, 9);
        printf("after:%d
    ", 9);
        print_avl_tree(root);
    
        ret = avl_find(root, 7);
        printf("find 7 result is %d
    ", ret);
    
        ret = avl_find(root, 17);
        printf("find 17 result is %d
    ", ret);
    
        ret = avl_del(&root, 7);
        printf("del 7 result is %d
    ", ret);
        print_avl_tree(root);
    
        ret = avl_del(&root, 17);
        printf("del 17 result is %d
    ", ret);
        print_avl_tree(root);
    
    
    
        avl_del_tree(root);
        return 0;
    }
    

      

    #gcc -g main.c avl.c -o main

    #./main

    hello, world
    root:address 27951120
    after:7
    7 0
    after:6
    6 0
    7 1
    after:5
    5 0
    6 1
    7 0
    after:7
    5 0
    6 1
    7 0
    after:1
    1 0
    5 1
    6 2
    7 0
    after:0
    0 0
    1 1
    5 0
    6 2
    7 0
    after:9
    0 0
    1 1
    5 0
    6 2
    7 1
    9 0
    find 7 result is 1
    find 17 result is 2
    del 7 result is 0
    0 0
    1 1
    5 0
    6 2
    9 0
    del 17 result is 0
    0 0
    1 1
    5 0
    6 2
    9 0

    应该是正确的。

     

  • 相关阅读:
    MFC+WinPcap编写一个嗅探器之六(分析模块)
    MFC+WinPcap编写一个嗅探器之五(过滤模块)
    MFC+WinPcap编写一个嗅探器之四(获取模块)
    MFC+WinPcap编写一个嗅探器之三(WinPcap)
    MFC+WinPcap编写一个嗅探器之二(界面)
    MFC+WinPcap编写一个嗅探器之一(准备)
    PHP单例模式
    apache url rewrite 的RewriteRule参数详解
    利用Httponly提升web应用程序安全性
    批量更新多条记录的不同值
  • 原文地址:https://www.cnblogs.com/igloo1986/p/3574636.html
Copyright © 2011-2022 走看看