[算法] 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\t%d\n", 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\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树实现的更多相关文章
- 数据结构与算法——AVL树类的C++实现
关于AVL树的简单介绍能够參考:数据结构与算法--AVL树简单介绍 关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法--二叉查找树类的C++实现 AVL-tree是一个"加上了额外 ...
- 数据结构和算法(Golang实现)(28)查找算法-AVL树
AVL树 二叉查找树的树高度影响了查找的效率,需要尽量减小树的高度,AVL树正是这样的树. 一.AVL树介绍 AVL树是一棵严格自平衡的二叉查找树,1962年,发明者Adelson-Velsky和La ...
- [数据结构与算法] : AVL树
头文件 typedef int ElementType; #ifndef _AVLTREE_H_ #define _AVLTREE_H_ struct AvlNode; typedef struct ...
- 数据结构和算法(Golang实现)(29)查找算法-2-3树和左倾红黑树
某些教程不区分普通红黑树和左倾红黑树的区别,直接将左倾红黑树拿来教学,并且称其为红黑树,因为左倾红黑树与普通的红黑树相比,实现起来较为简单,容易教学.在这里,我们区分开左倾红黑树和普通红黑树. 红黑树 ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- AVL树的平衡算法(JAVA实现)
1.概念: AVL树本质上还是一个二叉搜索树,不过比二叉搜索树多了一个平衡条件:每个节点的左右子树的高度差不大于1. 二叉树的应用是为了弥补链表的查询效率问题,但是极端情况下,二叉搜索树会无限接近 ...
- [算法] 数据结构之AVL树
1 .基本概念 AVL树的复杂程度真是比二叉搜索树高了整整一个数量级——它的原理并不难弄懂,但要把它用代码实现出来还真的有点费脑筋.下面我们来看看: 1.1 AVL树是什么? AVL树本质上还是一棵 ...
- AVL树的算法思路整理
http://www.cnblogs.com/heqile/archive/2011/11/28/2265713.html 看完了<数据结构与算法分析(C++描述)>的4.4节AVL树,做 ...
- 红黑树和AVL树的实现与比较-----算法导论
一.问题描述 实现3种树中的两种:红黑树,AVL树,Treap树 二.算法原理 (1)红黑树 红黑树是一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是red或black.红黑树满足以 ...
随机推荐
- HTML/CSS font-family对应的中英文名称 宋体 微软雅黑
宋体 SimSun 黑体 SimHei 微软雅黑 Microsoft YaHei 微软正黑体 Microsoft JhengHei 新宋体 NSimSun 新细明体 PMingLiU 细明体 Ming ...
- 笨方法学python--多行,转义序列
1 输入多行字符串的方法有2个,一个是使用换行符 \n.另一个是使用 "三引号". 2 针对不同的符号,有很多这样的"转义序列"(escape sequence ...
- .net获取根目录的方法集合
编写程序的时候,经常需要用的项目根目录.自己总结如下 .取得控制台应用程序的根目录方法 方法1.Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径 方法2. ...
- java设计模式案例详解:工厂模式
1.简单工厂模式 在不考虑扩展的情况下还是很好用的,其实我们写代码也很经常用到,其主要理解在于传入不同参数则构建不同对象,只有一个工厂,如需添加产品涉及到扩展需要修改比较多的东西,不符合开闭原则,如下 ...
- hdu 5344 MZL's xor
MZL's xor Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- ios 获得版本号
获取iphone的系统信息使用[UIDevice currentDevice],信息如下: [[UIDevice currentDevice] systemName]:系统名称,如iPhone OS ...
- php 代码编写的格式
1.代码标记 php程序可以使用<?php .... ?> 或 <? ..... ?> 来界定php代码,在html页面中嵌入纯变量是,可以使用<?= $variabl ...
- mysql中的substr()函数
mysql中的substr()函数和hibernate的substr()参数都一样,就是含义有所不同. 用法: substr(string string,num start,num length); ...
- div里面的margin-top失效
div标签中的元素margin-top失效的解决方法 元素上级标签是div,已经设置了width和height等的属性,可是,在对元素使用margin进行调整的时候,无法生效,下面有个不错的解决方法, ...
- Linux学习 -- Shell编程 -- 字符处理命令
sort排序命令 sort [选项] 文件名 -f 忽略大小m写 -n 按数值型,默认字符串型 -r 反向 -t 指定分隔符 -k n[,m] 指定字段范围,默认行尾 eg. sort -n -t & ...