首页 > 其他 > 详细

[算法] avl树实现

时间:2014-03-01 20:16:28      阅读:551      评论:0      收藏:0      [点我收藏+]

大二的时候数据结构课死活没看懂的一个东东,看了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
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

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"
 
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\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"
 
int main() {
    struct AVLNode *root = NULL;
    int ret = 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);
    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

 

应该是正确的。

 

 

[算法] avl树实现,布布扣,bubuko.com

[算法] avl树实现

原文:http://www.cnblogs.com/igloo1986/p/3574636.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!