/* * avl.h */ #ifndef _AVL_H #define _AVL_H typedef struct _avl_node { int data; int height; struct _avl_node *left; struct _avl_node *right; }avl_node; extern int init_avl_tree(avl_node **root, int value); extern void delete_avl_tree(avl_node *root); extern avl_node* avl_search(avl_node *root, int value); extern avl_node* avl_insert(avl_node *root, int value); extern int avl_delete(avl_node **root, int value); extern int avl_height(avl_node *root); extern void avl_print_preorder(avl_node *root); #endif /* * avl.c */ #include <stdio.h> #include <stdlib.h> #include "avl.h" static avl_node* avl_rotate_single_LL(avl_node *root); static avl_node* avl_rotate_single_RR(avl_node *root); static avl_node* avl_rotate_double_LR(avl_node *root); static avl_node* avl_rotate_double_RL(avl_node *root); static avl_node* avl_delete_node(avl_node *root, int value); int init_avl_tree(avl_node **root, int value) { if((*root = (avl_node *)malloc(sizeof(avl_node))) == NULL) { return -1; } (*root)->data = value; (*root)->height = 1; (*root)->left = NULL; (*root)->right = NULL; return 0; } void delete_avl_tree(avl_node *root) { if(root) { delete_avl_tree(root->left); delete_avl_tree(root->right); free(root); } } avl_node* avl_search(avl_node *root, int value) { avl_node *cur = root; while(cur) { if(cur->data == value) { break; } else if(cur->data > value) { cur = cur->left; } else { cur = cur->right; } } return cur; } avl_node* avl_insert(avl_node *root, int value) { if(!root) { root = (avl_node *)malloc(sizeof(avl_node)); if(!root) { printf("avl_insert: malloc error!/n"); } else { root->data = value; root->height = 1; root->left = NULL; root->right = NULL; } } else { if(root->data < value) { if((root->right = avl_insert(root->right, value)) != NULL) { if(avl_height(root->left) - avl_height(root->right) == -2) { if(root->right->data > value) { /* single retate: RL */ root = avl_rotate_double_RL(root); } else { /* double retate: RR */ root = avl_rotate_single_RR(root); } } } } else if(root->data > value) { if((root->left = avl_insert(root->left, value)) != NULL) { if(avl_height(root->left) - avl_height(root->right) == 2) { if(root->left->data > value) { /* single retate: LL */ root = avl_rotate_single_LL(root); } else { /* double retate: LR */ root = avl_rotate_double_LR(root); } } } } root->height = (avl_height(root->left) > avl_height(root->right) ? avl_height(root->left) : avl_height(root->right)) + 1; } return root; } int avl_delete(avl_node **root, int value) { *root = avl_delete_node(*root, value); return 0; } int avl_height(avl_node *tree) { if(tree) { return tree->height; } return 0; } static avl_node* avl_rotate_single_LL(avl_node *root) { avl_node *ret = root->left; root->left = ret->right; ret->right = root; root->height = (avl_height(root->left) > avl_height(root->right) ? avl_height(root->left) : avl_height(root->right)) + 1; ret->height = (avl_height(ret->left) > avl_height(ret->right) ? avl_height(ret->left) : avl_height(ret->right)) + 1; return ret; } static avl_node* avl_rotate_single_RR(avl_node *root) { avl_node *ret = root->right; root->right = ret->left; ret->left = root; root->height = (avl_height(root->left) > avl_height(root->right) ? avl_height(root->left) : avl_height(root->right)) + 1; ret->height = (avl_height(ret->left) > avl_height(ret->right) ? avl_height(ret->left) : avl_height(ret->right)) + 1; return ret; } static avl_node* avl_rotate_double_LR(avl_node *root) { root->left = avl_rotate_single_RR(root->left); return avl_rotate_single_LL(root); } static avl_node* avl_rotate_double_RL(avl_node *root) { root->right = avl_rotate_single_LL(root->right); return avl_rotate_single_RR(root); } void avl_print_preorder(avl_node *root) { if(root) { printf("%d [height: %d] ", root->data, root->height); if(root->left) { printf("[left: %d] ", root->left->data); } if(root->right) { printf("[right: %d] ", root->right->data); } printf("/n"); avl_print_preorder(root->left); avl_print_preorder(root->right); } } /* 删除操作思路来自 二叉排序树 */ static avl_node* avl_delete_node(avl_node *root, int value) { if(root) { if(root->data == value) { avl_node *tmp; if(root->right) { /* 找到 root->right 的最左儿子代替 root, 换成删除叶子节点 */ tmp = root->right; while(tmp->left) { tmp = tmp->left; } root->data = tmp->data; root->right = avl_delete_node(root->right, tmp->data); if(avl_height(root->left) - avl_height(root->right) == 2) { if(avl_height(root->left->left) >= avl_height(root->left->right)) { /* single retate: LL */ root = avl_rotate_single_LL(root); } else { /* double retate: LR */ root = avl_rotate_double_LR(root); } } } else { /* 如果 root 的右儿子为空则直接删除 */ tmp = root; root = root->left; free(tmp); return root; } } else if(root->data < value) { root->right = avl_delete_node(root->right, value); if(avl_height(root->left) - avl_height(root->right) == 2) { if(avl_height(root->left->left) >= avl_height(root->left->right)) { /* single retate: LL */ root = avl_rotate_single_LL(root); } else { /* double retate: LR */ root = avl_rotate_double_LR(root); } } } else { root->left = avl_delete_node(root->left, value); if(avl_height(root->left) - avl_height(root->right) == -2) { if(avl_height(root->right->left) >= avl_height(root->right->right)) { /* double retate: RL */ root = avl_rotate_double_RL(root); } else { /* single retate: RR */ root = avl_rotate_single_RR(root); } } } root->height = (avl_height(root->left) > avl_height(root->right) ? avl_height(root->left) : avl_height(root->right)) + 1; } return root; } void avl_test_app(void) { avl_node *root = NULL; int s, v; init_avl_tree(&root, 19); while(1) { printf("/n******************************/n"); printf("0: exit/n"); printf("1: print/n"); printf("2: find/n"); printf("3: depth/n"); printf("4: insert/n"); printf("5: delete/n"); printf("******************************/n"); printf("select: "); scanf("%d", &s); if(s == 0) { delete_avl_tree(root); return; } else if(s == 1) { avl_print_preorder(root); } else if(s == 2 || s == 4 || s == 5) { printf("value: "); scanf("%d", &v); if(avl_search(root, v) == NULL) { if(s == 4) { root = avl_insert(root, v); } else if(s == 5) { printf("not exists fail delete/n"); } else { printf("not exists/n"); } } else { if(s == 5) { if(!avl_delete(&root, v)) { printf("deleted/n"); } else { printf("fail delete/n"); } } else { printf("already exists/n"); } } } else if(s == 3) { printf("height: %d/n", avl_height(root)); } } }