AVL树问题
来源:互联网 发布:python的垃圾回收机制 编辑:程序博客网 时间:2024/06/13 04:11
AVL树不同于平衡搜索树,它有一个平衡因子的概念。
AVL树要满足两个条件:
1、平衡搜索树(左孩子<节点<右孩子)
2、就是每个节点的左右孩子的高度查的绝对值<=1。
见代码:
/* * prototype.c * * * * Copyright (C) 2012-10-17 liutos mat.liutos@gmail.com */#include <stdlib.h>#include <stdio.h>#include <math.h>#include <string.h>typedef struct node { void *value; /* char *value; */ int height; int bf; /* balance factor */ struct node *parent, *left, *right;} *AVLTree;int (*node_comparator)(struct node *node1, struct node *node2); /* Compares two nodes. If equal, returns zero; If node1 is greater then node2, returns a positive integer; otherwise, returns a negative integer. */char *(*node_name_maker)(struct node *); /* For generating a string represents a node. */char *(*node_value_maker)(struct node *); /* For generating a string represents the value of a node. */struct node *make_node(void *value){ struct node *node = malloc(sizeof(struct node)); node->value = value; node->height = 0; node->parent = node->left = node->right = NULL; return node;}void free_node(struct node *node){ free(node);}int get_tree_height(AVLTree tree){ return NULL == tree? -1: tree->height;}int get_max(int a, int b){ return a > b? a: b;}int compute_tree_height(AVLTree tree){ return get_max(get_tree_height(tree->left), get_tree_height(tree->right)) + 1;}int compute_tree_bf(AVLTree tree){ return get_tree_height(tree->left) - get_tree_height(tree->right);}AVLTree left_rotate(AVLTree tree){ AVLTree tmp; tmp = tree->right; tree->right = tmp->left; tmp->left = tree; tmp->bf = 0; tree->bf = 0; tree->height = compute_tree_height(tree); /* Update the tree->height first. */ tmp->height = compute_tree_height(tmp); /* Update the height of the root of the new tree. */ return tmp;}AVLTree right_rotate(AVLTree tree){ AVLTree tmp; tmp = tree->left; tree->left = tmp->right; tmp->right = tree; tmp->bf = 0; tree->bf = 0; tree->height = compute_tree_height(tree); /* The same as the left_rotate. */ tmp->height = compute_tree_height(tmp); return tmp;}AVLTree insert_node(struct node *node, AVLTree tree){ if (NULL == tree) return node; if (0 == node_comparator(node, tree)) { printf("%s already exists.\n", node_value_maker(node)); return tree; } if (node_comparator(node, tree) > 0) { /* Insert into the right subtree. */ tree->right = insert_node(node, tree->right); tree->right->parent = tree; tree->height = compute_tree_height(tree); tree->bf = compute_tree_bf(tree); /* If both tree->bf and tree->right->bf are negative, it's the case of RR. */ if (-2 == tree->bf && -1 == tree->right->bf) tree = left_rotate(tree); /* If tree->bf is negative and tree->right->bf is positive, it's the case of RL. */ else if (-2 == tree->bf && 1 == tree->right->bf) { tree->right = right_rotate(tree->right); tree = left_rotate(tree); } } else if (node_comparator(node, tree) < 0 ) { /* Insert into the left subtree. */ tree->left = insert_node(node, tree->left); tree->left->parent = tree; tree->height = compute_tree_height(tree); tree->bf = compute_tree_bf(tree); /* If both tree->bf and tree->left->bf are positive, it's the case of LL. */ if (2 == tree->bf && 1 == tree->left->bf) tree = right_rotate(tree); /* If tree->bf is positive and tree->left->bf is negative, it's the case of LR. */ else if (2 == tree->bf && -1 == tree->left->bf) { tree->left = left_rotate(tree->left); tree = right_rotate(tree); } } return tree;}/* Free the memory of a AVLTree in postorder. */void free_tree(AVLTree tree){ struct node *node; while (tree != NULL) { free_tree(tree->left); node = tree; tree = tree->right; free_node(node); }}void draw_tree_core(AVLTree tree, FILE *fp){ if (NULL) return; if (tree->left != NULL) { fprintf(fp, "\t%s:l -> %s;\n", node_name_maker(tree), node_name_maker(tree->left)); draw_tree_core(tree->left, fp); } if (tree->right != NULL) { fprintf(fp, "\t%s:r -> %s;\n", node_name_maker(tree), node_name_maker(tree->right)); draw_tree_core(tree->right, fp); }}void gen_node_description(struct node *node, FILE *fp){ fprintf(fp, "\t%s [label = \"<l> |{<v> value: %s| height: %d| bf: %d}|<r>\"];\n", node_name_maker(node), node_value_maker(node), node->height, node->bf);}void gen_tree_description(AVLTree tree, FILE *fp){ if (NULL == tree) return; gen_tree_description(tree->left, fp); gen_tree_description(tree->right, fp); gen_node_description(tree, fp);}void draw_tree(AVLTree tree){ FILE *fp = fopen("tree.dot", "w"); if (NULL == fp) { printf("Can not open file `tree.dot'.\n"); exit(1); } fprintf(fp, "digraph G {\n\tnode [shape = record];\n"); gen_tree_description(tree, fp); draw_tree_core(tree, fp); fprintf(fp, "}");}/* Used when the value is of type `int'. */int node_num_compare(struct node *node1, struct node *node2){ return node1->value - node2->value;}/* The string version. */int node_str_compare(struct node *node1, struct node *node2){ return strcmp(node1->value, node2->value);}/* Used when the value is of type `int'. */char *node_num_label(struct node *node){ char *label = malloc(10 * sizeof(char)); sprintf(label, "node%d", (int)node->value); return label;}/* The string version. */char *node_str_label(struct node *node){ return (char *)node->value;}/* The string version. */char *node_str_value(struct node *node){ return (char *)node->value;}/* Used when the value is of type `int'. */char *node_num_value(struct node *node){ char *value = malloc(10 * sizeof(char)); sprintf(value, "%d", (int)node->value); return value;}void preorder_traversal_avl(AVLTree tree){ if (NULL == tree) return; else { printf("%d", (int)tree->value); preorder_traversal_avl(tree->left); preorder_traversal_avl(tree->right); }}void inorder_traversal_avl(AVLTree tree){ if (NULL == tree) return; else { inorder_traversal_avl(tree->left); printf("%d", (int)tree->value); inorder_traversal_avl(tree->right); }}int main(int argc, char *argv[]){ /* char *datum[] = { */ /* "ls", */ /* "mkdir", */ /* "rm", */ /* "dot", */ /* "sbcl", */ /* "fg", */ /* "bg", */ /* "ghci", */ /* "ocamlc", */ /* }; */ int datum[] = {1, 2, 3, 4, 5, 8, 7, 6, 9}; int datum_len = sizeof(datum) / sizeof(int); int i; AVLTree tree = NULL; struct node *node; node_comparator = node_num_compare; node_name_maker = node_num_label; node_value_maker = node_num_value; /* node_comparator = node_str_compare; */ /* node_name_maker = node_str_label; */ /* node_value_maker = node_str_value; */ for (i = 0; i < datum_len; i++) { node = make_node((void *)datum[i]); tree = insert_node(node, tree); } /* draw_tree(tree); */ inorder_traversal_avl(tree); printf("\n"); free_tree(tree); return 0;}代码来源:https://github.com/Liutos/CLab/blob/master/avl/prototype.c
实现原理:
刚开始是空树,然后每次插入一个节点(按照平衡搜索树的条件插入)。插入以后对树的节点计算平衡因子,如果不满足AVL树的要求。则进行相应的调整(所谓的旋转)。
0 0
- AVL树问题
- AVL树(旋转问题详解)
- AVL树
- AVL树
- AVL树
- avl树
- AVL树
- avl树
- AVL树
- AVL树
- AVL树
- AVL树
- avl树
- avl树
- AVL树
- AVL树
- AVL树
- AVL树
- C4...
- Ubuntu 14.04 sougou
- Mac 登录界面多了一个其他账户删除
- 让eclipse完全支持HTML/JS/CSS智能提示
- 基准芯片参数里面的SOLDER HEAT SHIFT是什么概念?
- AVL树问题
- 电影TS、TC、SCR、R5、BD、HD等版本是什么意思
- Oracle PL/SQL复合数据类型
- WCF 学习总结2 -- 配置WCF
- 开发 WebLogic Server 的 Web 应用程序、Servlet 和 JSP
- jQuery的三种$()
- Java nio 之 概述
- WebKit库的使用
- deepin 2014.1下Qt creator 无法切换中文输入法