大二的时候数据结构课死活没看懂的一个东东,看了2小时,敲了2小时,调了2小时。。。
平衡树某一节点的左右子树高度相差大于1的时候即需要调整,调整可分为四中情况 ll,rr,lr,rl其中lr,rl是由不同顺序的ll,rr来实现的,代码比想象的简短。
一棵平衡的树只有在插入和删除节点的时候,才会变的不平衡,所以掌握好时机,判断平衡是否破坏及不平衡的种类,再纠正即可
代码如下。。
avl.h
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | structAVLNode {    structAVLNode *left;    structAVLNode *right;    intdata;    intheight;};staticconstintAVL_STATUS_OK = 0;staticconstintAVL_STATUS_FOUNDED = 1;staticconstintAVL_STATUS_NOTFOUNDED = 2;staticconstintAVL_STATUS_FAILED = -1;intavl_insert(structAVLNode **root, intdata);intavl_find(structAVLNode *root, intdata);intavl_del(structAVLNode **root, intdata);intavl_del_tree(structAVLNode *root);voidprint_avl_tree(structAVLNode *root);int_get_height(structAVLNode *node);int_max(inta, intb);void_single_rotate_left(structAVLNode **node);void_single_rotate_right(structAVLNode **node);void_double_rotate_left_right(structAVLNode **node);void_double_rotate_right_left(structAVLNode **node); | 
avl.c
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | #include <stdio.h>#include <stdlib.h>#include <assert.h>#include "avl.h"intavl_insert(structAVLNode **ptr_root, intdata) {    intret;    if(NULL == *ptr_root) {        *ptr_root = malloc(sizeof(structAVLNode));        if(NULL == *ptr_root) {            returnAVL_STATUS_FAILED;        }        (*ptr_root)->data = data;        (*ptr_root)->left = NULL;        (*ptr_root)->right = NULL;        (*ptr_root)->height = 0;        returnAVL_STATUS_OK;    }    if(data == (*ptr_root)->data) {        returnAVL_STATUS_OK;    }    elseif(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;    returnret;}intavl_find(structAVLNode *root, intdata) {    if(NULL == root) {        returnAVL_STATUS_NOTFOUNDED;    }    if(data == root->data) {        returnAVL_STATUS_FOUNDED;    }    if(data < root->data) {        returnavl_find(root->left, data);    }    else{        returnavl_find(root->right, data);    }}intavl_del(structAVLNode **root, intdata) {    structAVLNode *t;    if(*root == NULL) {        returnAVL_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);            }        }    }    elseif(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;            }            elseif((*root)->right == NULL) {                *root = (*root) -> left;            }            free(t);        }    }    returnAVL_STATUS_OK;}intavl_del_tree(structAVLNode *root) {    if(NULL == root) {        returnAVL_STATUS_OK;    }    avl_del_tree(root->left);    avl_del_tree(root->right);    free(root);    returnAVL_STATUS_OK;}int_get_height(structAVLNode *node) {    if(NULL == node){        return-1;    }    else{        returnnode->height;    }}int_max(inta, intb) {    returna > b ? a:b;}void_single_rotate_left(structAVLNode **node) {    structAVLNode* 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(structAVLNode **node) {    structAVLNode* 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(structAVLNode **node) {    structAVLNode* root = *node;    _single_rotate_right(&(root->left));    _single_rotate_left(node);}void_double_rotate_right_left(structAVLNode **node) {    structAVLNode* root = *node;    _single_rotate_left(&(root->right));    _single_rotate_right(node);}voidprint_avl_tree(structAVLNode *node) {    if(NULL == node) {        return;    }    print_avl_tree(node->left);    printf("%d\t%d\n", node->data, node->height);    print_avl_tree(node->right);} | 
main.c
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <stdio.h>#include "avl.h"intmain() {    structAVLNode *root = NULL;    intret = avl_insert(&root, 7);    printf("hello, world\n");    printf("root:address %ld\n", (long)root);    printf("after:%d\n", 7);    print_avl_tree(root);    avl_insert(&root, 6);    printf("after:%d\n", 6);    print_avl_tree(root);    avl_insert(&root, 5);    printf("after:%d\n", 5);    print_avl_tree(root);    avl_insert(&root, 7);    printf("after:%d\n", 7);    print_avl_tree(root);    avl_insert(&root, 1);    printf("after:%d\n", 1);    print_avl_tree(root);    avl_insert(&root, 0);    printf("after:%d\n", 0);    print_avl_tree(root);    avl_insert(&root, 9);    printf("after:%d\n", 9);    print_avl_tree(root);    ret = avl_find(root, 7);    printf("find 7 result is %d\n", ret);    ret = avl_find(root, 17);    printf("find 17 result is %d\n", ret);    ret = avl_del(&root, 7);    printf("del 7 result is %d\n", ret);    print_avl_tree(root);    ret = avl_del(&root, 17);    printf("del 17 result is %d\n", ret);    print_avl_tree(root);    avl_del_tree(root);    return0;} | 
#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
应该是正确的。
原文:http://www.cnblogs.com/igloo1986/p/3574636.html