AVL树的特征
1 AVL树 仍然是 左 子 结点 小于 父 结点, 父 结点 小于 右 子 结点
2 AVL树 AVL 树( Adel' son- Vel' skii and Landis) 是一 种 特殊 类型 的 二 叉 树, 它的 每个 结点 都 保存 一份 额外 的 信息: 结点 的 平衡 因子。
3 AVL 树 需要 自我 调整, 使得 所有 结点 的 平衡 因子 保持 为+ 1、- 1 或 0。 当子 树 的 根 结点 平衡 因子 为+ 1 时, 它是 左 倾斜 的( left- heavy)。 当子 树 的 根 结点 平衡 因子 为- 1 时, 它是 右 倾斜 的
4 AVL 树( Adel' son- Vel' skii and Landis) 是一 种 特殊 类型 的 二 叉 树, 它的 每个 结点 都 保存 一份 额外 的 信息: 结点 的 平衡 因子。
avl树 是在二叉树的基础上对数据进行了特俗的处理,我们任然可以复用树的实现和链表代码
list.h和list.c tree.c和tree.h请复用以前的代码
总的来说,其实以前的树的机构不变。在*data指针的数据里面新增了两个字段,一个是平衡参数,一个是是否隐藏,通过两个参数来实现平衡。
头文件
//
// avltree.h
// bsearchtree
//
// Created by bikang on 16/9/27.
// Copyright (c) 2016年 bikang. All rights reserved.
//
#ifndef __bsearchtree__avltree__
#define __bsearchtree__avltree__
#include "tree.h"
#define AVL_LEFT_HEAVY 1
#define AVL_BLANCED 0
#define AVL_RIGHT_HEAVY -1
typedef struct AvlNode_{
void *data;
int hidden;
int factor;
}AvlNode;
typedef BitTree BisTree;
void bistree_init(BisTree *tree,int (*compare)(const void *k1,const void *k2),void (*destroy)(void *data));
void bistree_destroy(BisTree *tree);
int bistree_insert(BisTree *tree,const void *data);
int bistree_remove(BisTree *tree,const void *data);
int bistree_lookup(BisTree *tree,void **data);
#define bistree_size(tree) ((tree)->size)
#endif /* defined(__bsearchtree__avltree__) */
实现代码
//
// avltree.c
// bsearchtree
//
// Created by bikang on 16/9/27.
// Copyright (c) 2016年 bikang. All rights reserved.
//
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "avltree.h"
static void destroy_right(BisTree *tree,BitTreeNode *node);
//左边旋转-节点指针
static void rotate_left(BitTreeNode **node)
{
BitTreeNode *left,*grandchild;
left = bitree_left(*node);
//左子树超重
if((((AvlNode*)bitree_data(left))->factor) == AVL_LEFT_HEAVY){
//处理Left left超重
bitree_left(*node) = bitree_right(left);
bitree_right(left) = *node;
((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
((AvlNode*)bitree_data(left))->factor = AVL_BLANCED;
*node = left;
}else{
//处理left right超重
grandchild = bitree_right(left);
bitree_right(left) = bitree_left(grandchild);//step 1
bitree_left(grandchild) = left;//step 2
bitree_left(*node) = bitree_right(grandchild);//step 3
bitree_right(grandchild) = *node;//step4
//调整平衡参数
switch (((AvlNode*)bitree_data(grandchild))->factor) {
case AVL_LEFT_HEAVY:
((AvlNode*)bitree_data(*node))->factor = AVL_RIGHT_HEAVY;
((AvlNode*)bitree_data(left))->factor = AVL_BLANCED;
break;
case AVL_BLANCED:
((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
((AvlNode*)bitree_data(left))->factor = AVL_BLANCED;
break;
case AVL_RIGHT_HEAVY:
((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
((AvlNode*)bitree_data(left))->factor = AVL_LEFT_HEAVY;
break;
}
((AvlNode*)bitree_data(grandchild))->factor = AVL_BLANCED;
*node = grandchild;
}
return;
}
//类似左旋转,只是方向不一样
static void rotate_right(BitTreeNode **node){
BitTreeNode *right,*grandchild;
right = bitree_right(*node);
if((((AvlNode*)bitree_data(right))->factor) == AVL_RIGHT_HEAVY){
//处理RR的情况
bitree_right(*node) = bitree_left(right);
bitree_left(right) = *node;
((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
((AvlNode*)bitree_data(right))->factor = AVL_BLANCED;
*node = right;
}else{
grandchild = bitree_left(right);
bitree_left(right) = bitree_right(grandchild);//step1
bitree_right(grandchild) = right;//step2
bitree_right(*node) = bitree_left(grandchild);//step3
bitree_left(grandchild) = *node;//step4
//调整平衡参数
switch (((AvlNode*)bitree_data(grandchild))->factor) {
case AVL_LEFT_HEAVY:
((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
((AvlNode*)bitree_data(right))->factor = AVL_RIGHT_HEAVY;
break;
case AVL_BLANCED:
((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
((AvlNode*)bitree_data(right))->factor = AVL_BLANCED;
break;
case AVL_RIGHT_HEAVY:
((AvlNode*)bitree_data(*node))->factor = AVL_LEFT_HEAVY;
((AvlNode*)bitree_data(right))->factor = AVL_BLANCED;
break;
}
((AvlNode*)bitree_data(grandchild))->factor = AVL_BLANCED;
*node = grandchild;
}
return;
}
static void destroy_left(BisTree *tree, BitTreeNode *node){
BitTreeNode **position;
if(bitree_size(tree) == 0) return;
if(node == NULL){
position = &tree->root;
}else{
position = &node->left;
}
if (*position != NULL) {
destroy_left(tree, *position);
destroy_right(tree, *position);
if(tree->destroy != NULL){
tree->destroy((((AvlNode*)(*position)->data))->data);
}
free((*position)->data);
free(*position);
*position = NULL;
tree->size--;
}
return;
}
static void destroy_right(BisTree *tree,BitTreeNode *node){
BitTreeNode **position;
if(bitree_size(tree) == 0) return;
if(node == NULL){
position = &tree->root;
}else{
position = &node->right;
}
if (*position != NULL) {
destroy_left(tree, *position);
destroy_right(tree, *position);
if(tree->destroy != NULL){
tree->destroy((((AvlNode*)(*position)->data))->data);
}
free((*position)->data);
free(*position);
*position = NULL;
tree->size--;
}
return;
}
//插入数据,也是最关键的部分,每次插入都得平衡
static int insert(BisTree *tree,BitTreeNode **node,const void*data,int *balanced ){
AvlNode *avl_data;
int cmpval,retval;
//printf("*data=%d",*(int*)data);
if(bitree_is_eob(*node)){
if((avl_data =(AvlNode *)malloc(sizeof(AvlNode))) == NULL) return -1;
avl_data->factor = AVL_BLANCED;
avl_data->hidden = 0;
avl_data->data = (void*)data;
return bitree_ins_left(tree, *node, avl_data);
}else{
cmpval = tree->compare(data,((AvlNode *)(bitree_data(*node)))->data);
//printf("###node=%d,%d\n",*(int*)(((AvlNode*)bitree_data(*node))->data),cmpval);
if(cmpval < 0){
if(bitree_is_eob(bitree_left(*node))){
if((avl_data =(AvlNode *)malloc(sizeof(AvlNode))) == NULL) return -1;
avl_data->factor = AVL_BLANCED;
avl_data->hidden = 0;
avl_data->data = (void*)data;
if(bitree_ins_left(tree, *node, avl_data) != 0) return -1;
*balanced = 0;
}else{
//继续往左边寻找
if((retval = insert(tree,&bitree_left(*node),data,balanced)) !=0){
return retval;
}
}
//左子树非平衡的
if(!(*balanced)){
switch (((AvlNode*)bitree_data(*node))->factor) {
case AVL_LEFT_HEAVY:
rotate_left(node);
*balanced = 1;
break;
case AVL_BLANCED:
//如果左子树平衡,左边会重因为新插入元素
((AvlNode*)bitree_data(*node))->factor = AVL_LEFT_HEAVY;
break;
case AVL_RIGHT_HEAVY:
((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
*balanced = 1;
break;
}
}
}else if (cmpval > 0){
if(bitree_is_eob(bitree_right(*node))){
if((avl_data =(AvlNode *)malloc(sizeof(AvlNode))) == NULL) return -1;
avl_data->factor = AVL_BLANCED;
avl_data->hidden = 0;
avl_data->data = (void*)data;
if(bitree_ins_right(tree, *node, avl_data) != 0) return -1;
*balanced = 0;
}else{
if((retval = insert(tree,&bitree_right(*node),data,balanced)) !=0){
return retval;
}
}
if(!(*balanced)){
switch (((AvlNode*)bitree_data(*node))->factor)
{
case AVL_LEFT_HEAVY:
((AvlNode*)bitree_data(*node))->factor = AVL_BLANCED;
*balanced = 1;
break;
case AVL_BLANCED:
((AvlNode*)bitree_data(*node))->factor = AVL_RIGHT_HEAVY;
break;
case AVL_RIGHT_HEAVY:
rotate_right(node);
*balanced = 1;
break;
}
}
}else{
//数据已经存在
if(!((AvlNode*)bitree_data(*node))->hidden){
return 1;
}else{
//插入新的数据
if(tree->destroy!= NULL){
tree->destroy(((AvlNode*)bitree_data(*node))->data);
}
((AvlNode*)bitree_data(*node))->data = (void*)data;
((AvlNode*)bitree_data(*node))->hidden = 0;
*balanced = 1;
}
}
}
return 0;
}
static int hide(BisTree *tree,BitTreeNode *node,const void *data){
int cmpval,retval;
if(bitree_is_eob(node)) return -1;
cmpval = tree->compare(data,((AvlNode*)bitree_data(node))->data);
if(cmpval < 0){
retval = hide(tree,bitree_left(node),data);
}else if(cmpval > 0){
retval = hide(tree,bitree_right(node),data);
}else{
((AvlNode*)bitree_data(node))->hidden = 1;
retval = 0;
}
return retval;
}
static int lookup(BisTree *tree,BitTreeNode *node,const void **data){
int cmpval,retval;
if(bitree_is_eob(node)) return -1;
cmpval = tree->compare(*data,((AvlNode*)bitree_data(node))->data);
//printf("%d,%d,cmp=%d\n",**(int**)data,*(int*)((AvlNode*)bitree_data(node))->data,cmpval);
if(cmpval < 0){
retval = lookup(tree,bitree_left(node),data);
}else if(cmpval > 0){
retval = lookup(tree,bitree_right(node),data);
}else{
if(!((AvlNode*)bitree_data(node))->hidden){
*data =((AvlNode*)bitree_data(node))->data;
retval = 0;
}else{
return -1;
}
}
return retval;
}
void bistree_init(BisTree *tree,int (*compare)(const void *k1,const void *k2),void (*destroy)(void *data)){
bitree_init(tree, destroy);
tree->compare = compare;
return;
}
void bistree_destroy(BisTree *tree){
destroy_left(tree, NULL);
memset(tree,0,sizeof(BitTree));
return ;
}
int bistree_insert(BisTree *tree,const void *data){
int balance = 0;
return insert(tree,&bitree_root(tree),data,&balance);
}
int bistree_remove(BisTree *tree,const void *data){
return hide(tree,bitree_root(tree),data);
}
int bistree_lookup(BisTree *tree,void **data){
return lookup(tree, bitree_root(tree),(const void**)data);
}
测试代码
//
// main.c
// bsearchtree
//
// Created by bikang on 16/9/27.
// Copyright (c) 2016年 bikang. All rights reserved.
//
//AVL树 仍然是 左 子 结点 小于 父 结点, 父 结点 小于 右 子 结点
//AVL树 AVL 树( Adel' son- Vel' skii and Landis) 是一 种 特殊 类型 的 二 叉 树, 它的 每个 结点 都 保存 一份 额外 的 信息: 结点 的 平衡 因子。
//时, AVL 树 需要 自我 调整, 使得 所有 结点 的 平衡 因子 保持 为+ 1、- 1 或 0。 当子 树 的 根 结点 平衡 因子 为+ 1 时, 它是 左 倾斜 的( left- heavy)。 当子 树 的 根 结点 平衡 因子 为- 1 时, 它是 右 倾斜 的
//AVL 树( Adel' son- Vel' skii and Landis) 是一 种 特殊 类型 的 二 叉 树, 它的 每个 结点 都 保存 一份 额外 的 信息: 结点 的 平衡 因子。
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "tree.h"
#include "avltree.h"
//打印链表
void print_list_info(List *list);
//先序
int preorder_tree(const BitTreeNode *node,List *list);
//中序排序
int inorder_tree(const BitTreeNode *node,List *list);
//比较数据
int compare_int(const void *a,const void *b){
int a1 = *(int*)a;
int b1 = *(int*)b;
//printf("compare a1=%d,b1=%d\n",a1,b1);
if(a1 == b1){
return 0;
}else if(a1 > b1) {
return 1;
}else{
return -1;
}
}
void ttree();
int main(int argc, const char * argv[]) {
ttree();
return 0;
}
void ttree(){
int ret_val;
BisTree *tree = (BisTree*)malloc(sizeof(BisTree));
bistree_init(tree, compare_int, free);
List *list = (List *)malloc(sizeof(List));
list_init(list, NULL);
int bistree_insert(BisTree *tree,const void *data);
int a1 = 46;int *p1 = (int *)malloc(sizeof(int));*p1 = a1;
int a2 = 22;int *p2 = (int *)malloc(sizeof(int));*p2 = a2;
int a3 = 15;int *p3 = (int *)malloc(sizeof(int));*p3 = a3;
int a4 = 43;int *p4 = (int *)malloc(sizeof(int));*p4 = a4;
int a5 = 75;int *p5 = (int *)malloc(sizeof(int));*p5 = a5;
int a6 = 71;int *p6 = (int *)malloc(sizeof(int));*p6 = a6;
int a7 = 48;int *p7 = (int *)malloc(sizeof(int));*p7 = a7;
bistree_insert(tree, (void*)p1);
//插入
bistree_insert(tree, (void*)p2);
bistree_insert(tree, (void*)p3);
bistree_insert(tree, (void*)p4);
bistree_insert(tree, (void*)p5);
bistree_insert(tree, (void*)p6);
bistree_insert(tree, (void*)p7);
//查找
void **data = (void**)malloc(sizeof(int));
*data = p3;
ret_val = bistree_lookup(tree, data);
if(ret_val == 0){
puts("find ok");
}
//删除
bistree_remove(tree,p3);
//inorder_tree(bitree_root(tree),list);
//print_list_info(list);
preorder_tree(bitree_root(tree),list);
print_list_info(list);
bistree_destroy(tree);
list_destroy(list);
}
//中序遍历
int inorder_tree(const BitTreeNode *node,List *list){
if(!bitree_is_eob(node)){
if(!bitree_is_eob(bitree_left(node))){
if(inorder_tree(bitree_left(node),list) != 0){
return -1;
}
}
if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0) return -1;
if(!bitree_is_eob(bitree_right(node))){
if(inorder_tree(bitree_right(node),list) != 0){
return -1;
}
}
}
return 0;
}
//先序遍历
int preorder_tree(const BitTreeNode *node,List *list){
if(!bitree_is_eob(node)){
if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0) return -1;
if(!bitree_is_eob(bitree_left(node))){
if(preorder_tree(bitree_left(node),list) != 0){
return -1;
}
}
if(!bitree_is_eob(bitree_right(node))){
if(preorder_tree(bitree_right(node),list) != 0){
return -1;
}
}
}
return 0;
}
//打印一个列表
void print_list_info(List *list){
if(list_size(list) == 0){
printf("empty list\n");
return;
}
ListElmt *pl;
pl = list_head(list);
int i;
printf("\n#########start#############\n");
for(i=0;i<list_size(list);i++){
printf("data=%d ",*(int*)(((AvlNode*)list_data(pl))->data));
printf("hiden=%d ",(((AvlNode*)list_data(pl))->hidden));
printf("factor=%d ",(((AvlNode*)list_data(pl))->factor));
printf("\n");
pl = pl->next;
}
printf("\n#########end#############\n");
}