博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[重温数据结构]一种自平衡二叉查找树avl树的实现方法
阅读量:5295 次
发布时间:2019-06-14

本文共 6596 字,大约阅读时间需要 21 分钟。

 

最近重温《数据结构》,发现其中的东西我上学的时候几乎都没写过。。。 惭愧啊。于是打算一一写点。算是对我逝去青春的纪念。。。 

avl树的代码网上有很多, 这个在平衡二叉树里面算是比较简单的。 需要注意的就是树的平衡因子和其子树的平衡因子符号相反的旋转情况。这个在函数avl_rotate_right等中有处理. 目前只做了插入,删除等哪天想做了再做吧。

 

avl.h

1 #define INSERT_ERROR -1 2 #define INSERT_OK 1 3  4 #define LEFT_LEAN 2 5 #define RIGHT_LEAN -2 6 #define LEFT_LEAN_A_BIT 1 7 #define RIGHT_LEAN_A_BIT -1 8 #define NOT_LEAN 0 9 10 struct AvlNode;11 typedef struct AvlNode{12     struct AvlNode* left;          /*left sub tree*/13     struct AvlNode* right;         /*left sub tree*/14     unsigned int  key;       15     void *data;             16     unsigned int  height;   /*current height*/17  //   int bf;                 /*balance param*/18 }AvlNode;19 20 typedef struct {21     AvlNode *root;22 }AvlTree;23 24 25 extern int AvlInsert( AvlTree* tree,   void* data , int key );26 extern int AvlDel( AvlTree* tree,   int key  );27 extern void* AvlFindData( AvlTree* tree,   int key  );28 extern AvlTree* AvlCreateTree();

avl.c

1 #include 
2 #include
3 #include
4 #include "avl.h" 5 6 /************* 7 current: current sub-tree to be inserted 8 data : data to be inserted 9 key : key 10 **************/ 11 static int avl_insert_into(AvlNode** current, void* data,int key); 12 static void avl_rotate_left(AvlNode** current); 13 static void avl_rotate_right(AvlNode** current); 14 static AvlNode* avl_create_node(void* data, int key); 15 static unsigned avl_adjust_height(AvlNode* node); 16 static int avl_is_balance(AvlNode* node); 17 18 AvlNode* avl_create_node(void* data, int key) 19 20 { 21 AvlNode* node = malloc(sizeof(AvlNode)); 22 node->left = NULL; 23 node->right = NULL; 24 node->key = key; 25 node->data = data; 26 node->height = 1; 27 } 28 29 30 unsigned avl_adjust_height(AvlNode* node) 31 { 32 unsigned height; 33 if(!node->left && !node->right){ 34 node->height = 1; 35 return node->height; 36 } 37 if(!node->left){ 38 node->height = node->right->height + 1; 39 return node->height; 40 } 41 if(!node->right){ 42 node->height = node->left->height + 1; 43 return node->height; 44 } 45 node->height = node->left->height > node->right->height ? node->left->height + 1 : node->right->height + 1 ; 46 return node->height; 47 } 48 49 //if th avl tree is balance? the (left_h - right_h) is balance f 50 int avl_is_balance(AvlNode* current){ 51 unsigned left_h , right_h; 52 if(!current->left) 53 left_h = 0; 54 else 55 left_h = current->left->height; 56 57 if(!current->right) 58 right_h = 0; 59 else 60 right_h = current->right->height; 61 62 return left_h -right_h; 63 } 64 65 int avl_insert_into(AvlNode **current_addr, void *data,int key) 66 { 67 AvlNode *current = NULL; 68 69 if(!current_addr) 70 return INSERT_ERROR; 71 else 72 current= *current_addr; 73 74 if(!current){ 75 current = avl_create_node(data , key); 76 avl_adjust_height(current); 77 *current_addr = current; 78 return INSERT_OK; 79 } 80 81 /*insert into left or right*/ 82 if(key > current->key){ 83 if(INSERT_ERROR == avl_insert_into( &current->right, data, key )) 84 return INSERT_ERROR; 85 } else if(key < current->key) { 86 if(INSERT_ERROR == avl_insert_into( &current->left, data , key) ) 87 return INSERT_ERROR; 88 } else 89 return INSERT_ERROR; 90 91 avl_adjust_height(current); 92 /*if not balance rotate*/ 93 switch(avl_is_balance(current)) 94 { 95 case LEFT_LEAN: 96 avl_rotate_right(current_addr); 97 break; 98 case RIGHT_LEAN: 99 avl_rotate_left(current_addr);100 break;101 default:102 break;103 } 104 return INSERT_OK;105 }106 107 108 void avl_rotate_left(AvlNode **current_addr)109 {110 AvlNode *current = *current_addr;111 if( LEFT_LEAN_A_BIT == avl_is_balance(current->right) ) 112 avl_rotate_right(&current->right);113 114 AvlNode* tmp = current->right;115 current->right = current->right->left;116 tmp->left = current;117 current = tmp;118 *current_addr = tmp;119 avl_adjust_height(current->left);120 avl_adjust_height(current);121 }122 123 124 void avl_rotate_right(AvlNode **current_addr)125 {126 AvlNode *current = *current_addr;127 if( RIGHT_LEAN_A_BIT == avl_is_balance(current->left) ) {128 avl_rotate_left(&current->left);129 }130 AvlNode* tmp = current->left;131 current->left = current->left->right;132 tmp->right = current;133 current = tmp;134 *current_addr = tmp;135 avl_adjust_height(current->right);136 avl_adjust_height(current);137 }138 139 AvlTree* AvlCreateTree()140 {141 AvlTree* tree = (AvlTree*)malloc(sizeof(AvlTree));142 return tree;143 }144 145 int AvlInsert( AvlTree* tree, void* data , int key )146 {147 return avl_insert_into( &tree->root, data, key); 148 }149 150 int AvlDel( AvlTree* tree, int key )151 {152 return 0;153 }154 155 156 void* AvlFindData( AvlTree* tree, int key )157 {158 return NULL;159 }

testmain.c

1 #include "stdio.h" 2 #include "avl.h" 3  4  5 int main() 6 { 7     AvlTree* tree = AvlCreateTree(); 8     AvlInsert(tree, NULL, 1); 9     AvlInsert(tree, NULL, 3);10     AvlInsert(tree, NULL, 5);11     AvlInsert(tree, NULL, 7);12     AvlInsert(tree, NULL, 6);13     AvlInsert(tree, NULL, 9);14     AvlInsert(tree, NULL, 8);15     AvlInsert(tree, NULL, 0);16     AvlInsert(tree, NULL, 11);17     AvlInsert(tree, NULL, 4);18     AvlInsert(tree, NULL, 2);19 }

Makefile

PRJ_ROOT=$(pwd)CC=gccCFLAGS= -g  LDFLAGS= ###########源文件,每增加一个目标,依样增加下面一段##############源文件列表1i:=1SOURCES_C_$(i):= testmain.c  avl.c   #在这里添加、修改当前目标需要的C源码TARGET_$(i):=avl        #目标名称OBJS_C_$(i):= $(patsubst %.c,%.o, $(SOURCES_C_$(i)))OBJS_$(i):= $(OBJS_C_$(i))#######目标和清除 每增加一个目标,依样增加一个target##########all: $(TARGET_1)     @echo "outputfile : $(TARGET_1) "clean:    rm -f *.o  *.d  $(TARGET_1)##########目标, 每增加一个目标,依样增加下面一段##############目标1 $(TARGET_1):$(OBJS_1)    $(CC) $(OBJS_1) $(LDFLAGS) -o $(TARGET_1)###########包含 每增加一个目标,依样增加下面一行#############sinclude $(OBJS_1:.o=.d)#下面这边都是获取依赖关系 ,属于约定俗成的写法%.d: %.c    @rm -f $@;    @$(CC) -MM $< > $@.1111; \    sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.1111 > $@;  \    rm -f $@.1111

 

转载于:https://www.cnblogs.com/ministone/p/4183882.html

你可能感兴趣的文章
AJAX 基础知识
查看>>
HTML光标样式
查看>>
ACM-渊子赛马
查看>>
51nod 1384 全排列
查看>>
Linux下设置MySQL数据库存储特殊符号
查看>>
redux-saga框架使用详解及Demo教程
查看>>
Jmeter的线程组
查看>>
代码规范
查看>>
Django 错误之 No module named ‘MySQLdb’
查看>>
佳博80250打印机怎么看打印机IP
查看>>
[hdu4513]常规dp
查看>>
[hdu5521 Meeting]最短路
查看>>
HTTP 错误 500.22 - Internal Server Error
查看>>
ASIHTTPRequest框架官方文档
查看>>
qt,ui,QUiLoader
查看>>
494 - Kindergarten Counting Game
查看>>
Android 字体效果
查看>>
HDU 2103 Family Plan
查看>>
3.6.2投影峰谷查找
查看>>
小程序教程相关链接
查看>>