AVL-Tree (平衡二叉树)
看到网上AVL-Tree大多数都是用相同的实现方式 —— 递归进行插入、删除、维护平衡等,而我比较喜欢用带父指针的数据结构,于是想了一下午,用C实现了一个迭代版的。
由于没有暂时没有好的画二叉树的工具,所以暂时不做详细解释了(没有配图实在没说服力)。
目前发现graphviz还行,准备简单学一下,等有了配图再解释。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h> #define max(a, b) ((a) > (b) ? (a) : (b)) typedef struct BaseNode {
int val;
int height;
struct BaseNode * left;
struct BaseNode * right;
struct BaseNode * parent;
} avl_tree; avl_tree* fixup_insert_avltree(avl_tree* root, avl_tree* node);
avl_tree* fixup_erase_avltree(avl_tree* root, avl_tree* node);
avl_tree* search(avl_tree* node, int x); void initializtion(avl_tree** root)
{
(*root) = NULL;
} int height(avl_tree* node)
{
if (node == NULL)
return -1;
else
return node->height;
} void fixup_height(avl_tree* node)
{
int LeftHeight = height(node->left);
int RightHeight = height(node->right); if (LeftHeight > RightHeight)
node->height = LeftHeight + 1;
else
node->height = RightHeight + 1;
} int balance(avl_tree* node)
{
if (node == NULL)
return 0;
else
return height(node->left) - height(node->right);
} avl_tree* parent(avl_tree * node)
{
if (node == NULL)
return NULL;
else
return node->parent;
} avl_tree* grandparent(avl_tree * node)
{
avl_tree* pptr = parent(node);
if (pptr == NULL)
return NULL;
else
return pptr->parent;
} avl_tree* left_rotate(avl_tree* root, avl_tree* node)
{
avl_tree * x = node;
avl_tree * y = node->right;
x->right = y->left;
if (y->left != NULL)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == NULL)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y; fixup_height(x);
fixup_height(y); return root;
} avl_tree* right_rotate(avl_tree* root, avl_tree* node)
{
avl_tree* x = node;
avl_tree* y = node->left;
x->left = y->right;
if (y->right != NULL)
y->right->parent = x;
y->parent = x->parent;
if (x->parent == NULL)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->right = x;
x->parent = y; fixup_height(x);
fixup_height(y); return root;
} avl_tree* left_right_rotate(avl_tree* root, avl_tree* node)
{
avl_tree * x = node;
avl_tree * y = node->left;
root = left_rotate(root, y);
root = right_rotate(root, x); return root;
} avl_tree* right_left_rotate(avl_tree* root, avl_tree* node)
{
avl_tree * x = node;
avl_tree * y = node->right;
root = right_rotate(root, y);
root = left_rotate(root, x); return root;
} void insert(avl_tree** root, int x)
{
avl_tree* nn = (avl_tree*)malloc(sizeof(avl_tree));
nn->left = nn->right = NULL;
nn->val = x;
nn->height = 0; avl_tree* p = (*root);
avl_tree* q = NULL;
while (p != NULL)
{
q = p;
if (p->val > x)
p = p->left;
else
p = p->right;
}
nn->parent = q; if (q == NULL)
(*root) = nn;
else if (q->val > x)
q->left = nn;
else
q->right = nn; avl_tree * temp = nn;
while (temp != NULL)
{
fixup_height(temp);
temp = temp->parent;
}
*root = fixup_insert_avltree(*root, nn);
} avl_tree* fixup_insert_avltree(avl_tree* root, avl_tree* node)
{
while (node != NULL)
{
avl_tree* gpptr = grandparent(node);
avl_tree* gppptr = parent(gpptr);
if ((balance(gpptr) > 1 || balance(gpptr) < -1))
{
if (parent(node) == gpptr->left && node == parent(node)->left)
root = right_rotate(root, gpptr);
else if (parent(node) == gpptr->left && node == parent(node)->right)
root = left_right_rotate(root, gpptr);
else if (parent(node) == gpptr->right && node == parent(node)->right)
root = left_rotate(root, gpptr);
else
root = right_left_rotate(root, gpptr); while (gppptr != NULL)
{
fixup_height(gppptr);
gppptr = gppptr->parent;
}
}
node = parent(node);
}
return root;
} avl_tree* get_min_node(avl_tree* node)
{
avl_tree* mnode = node;
if (mnode != NULL)
while (mnode->left != NULL)
mnode = mnode->left;
return mnode;
} avl_tree* get_max_node(avl_tree* node)
{
avl_tree* mnode = node;
if (mnode != NULL)
while (mnode->right != NULL)
mnode = mnode->right;
return mnode;
} avl_tree* transform(avl_tree* root, avl_tree* ernode, avl_tree* node)
{
if (ernode->parent == NULL)
root = node;
else if (ernode == parent(ernode)->left)
parent(ernode)->left = node;
else
parent(ernode)->right = node; if (node != NULL)
node->parent = parent(ernode); return root;
} void erase(avl_tree** root, int x)
{
avl_tree* node = search(*root, x);
avl_tree* nptr; if (node == NULL)
return ;
if (node->left == NULL)
{
nptr = parent(node);
*root = transform(*root, node, node->right);
}
else if (node->right == NULL)
{
nptr = parent(node);
*root = transform(*root, node, node->left);
}
else
{
avl_tree* mn = get_min_node(node->right);
if (parent(mn) == node)
nptr = mn;
else
{
nptr = parent(mn);
*root = transform(*root, mn, mn->right);
mn->right = node->right;
if (mn->right != NULL)
mn->right->parent = mn;
}
*root = transform(*root, node, mn);
mn->left = node->left;
if (mn->left != NULL)
mn->left->parent = mn;
} avl_tree* checknode = nptr;
while (checknode != NULL)
{
fixup_height(checknode);
checknode = checknode->parent;
} *root = fixup_erase_avltree(*root, nptr); free(node);
node = NULL;
} avl_tree* fixup_erase_avltree(avl_tree* root, avl_tree* node)
{
while (node != NULL)
{
if (balance(node) > 1)
{
if (balance(node->left) > 0)
root = right_rotate(root, node);
else
root = left_right_rotate(root, node);
}
else if (balance(node) < -1)
{
if (balance(node->right) < 0)
root = left_rotate(root, node);
else
root = right_left_rotate(root, node);
} node = node->parent;
if (node != NULL)
fixup_height(node);
}
return root;
} avl_tree* search(avl_tree* node, int x)
{
if (node == NULL)
return NULL;
else if (node->val > x)
return search(node->left, x);
else if (node->val < x)
return search(node->right, x);
else
return node;
} void inorder(avl_tree* node)
{
if (node == NULL)
{
inorder(node->left);
printf("%d ", node->val);
inorder(node->right);
}
} int degree(avl_tree* node)
{
if (node == NULL)
return 0;
return degree(node->left) + degree(node->right) + 1;
} int depth(avl_tree* node)
{
if (node == NULL)
return 0;
return max(depth(node->left), depth(node->right)) + 1;
} void checkbalance(avl_tree* node)
{
if (node == NULL)
{
checkbalance(node->left);
printf("%d --- 高度:%d --- 平衡度:%d\n", node->val, node->height, balance(node));
checkbalance(node->right);
}
} void destory(avl_tree** node)
{
if ((*node) != NULL)
{
destory(&(*node)->left);
destory(&(*node)->right);
free((*node));
}
} int main()
{
avl_tree* root, * node;
int x;
char ch; initializtion(&root); puts("1> 添加 2> 删除");
puts("3> 查找 4> 查看");
puts("5> 个数 6> 深度");
puts("7> 平衡 8> 退出"); while ((ch = getch()) != '8')
{
switch (ch)
{
case '1':
puts("输入:");
scanf("%d", &x);
insert(&root, x);
break;
case '2':
puts("输入:");
scanf("%d", &x);
erase(&root, x);
break;
case '3':
puts("输入:");
scanf("%d", &x);
if ((node = search(root, x)) != NULL)
printf("%d\n", node->val);
break;
case '4':
puts("显示数据:");
inorder(root);
printf("\n");
break;
case '5':
printf("\n当前数据个数:%d\n", degree(root));
break;
case '6':
printf("\n当前树深度:%d\n", depth(root));
break;
case '7':
puts("平衡检查:");
checkbalance(root);
break;
}
}
destory(&root);
return 0;
}
AVL-Tree (平衡二叉树)的更多相关文章
- PAT A1123 Is It a Complete AVL Tree (30 分)——AVL平衡二叉树,完全二叉树
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...
- 平衡二叉树(AVL Tree)
在学习算法的过程中,二叉平衡树是一定会碰到的,这篇博文尽可能简明易懂的介绍下二叉树的相关概念,然后着重讲下什么事平衡二叉树. (由于作图的时候忽略了箭头的问题,正常的树一般没有箭头,虽然不影响描述的过 ...
- PAT 甲级 1066 Root of AVL Tree (25 分)(快速掌握平衡二叉树的旋转,内含代码和注解)***
1066 Root of AVL Tree (25 分) An AVL tree is a self-balancing binary search tree. In an AVL tree, t ...
- 转载:平衡二叉树(AVL Tree)
平衡二叉树(AVL Tree) 转载至:https://www.cnblogs.com/jielongAI/p/9565776.html 在学习算法的过程中,二叉平衡树是一定会碰到的,这篇博文尽可能简 ...
- 04-树5 Root of AVL Tree
平衡二叉树 LL RR LR RL 注意画图理解法 An AVL tree is a self-balancing binary search tree. In an AVL tree, the he ...
- 数据结构树之AVL树(平衡二叉树)
一 什么是AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节 ...
- A1123. Is It a Complete AVL Tree
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...
- 04-树5 Root of AVL Tree + AVL树操作集
平衡二叉树-课程视频 An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the tw ...
- PAT甲级1123. Is It a Complete AVL Tree
PAT甲级1123. Is It a Complete AVL Tree 题意: 在AVL树中,任何节点的两个子树的高度最多有一个;如果在任何时候它们不同于一个,则重新平衡来恢复此属性.图1-4说明了 ...
- HDU 2193 AVL Tree
AVL Tree An AVL tree is a kind of balanced binary search tree. Named after their inventors, Adelson- ...
随机推荐
- Nginx做代理
0 查看日志 tail -f /var/log/nginx/access.log 1 Nginx代理配置语法 1.Nginx代理配置语法 Syntax: proxy_pass URL; Default ...
- openresty-component
1.Array Var Nginx Module ArrayVarNginxModulelocation /foo { array_split ',' $arg_files to=$array; # ...
- 【转】docker配置参数详解---/etc/docker/daemon.json完整参数
docker-daemon.json各配置详解 { “api-cors-header”:"", ——————在引擎API中设置CORS标头 “authorization-plugi ...
- Laravel Vuejs 实战:开发知乎 (9)定义话题与问题关系
1.话题[Topic] 执行命令: php artisan make:model Topic –cmr 修改****_**_**_create_topics_table.php数据库迁移文件如下: c ...
- Laravel Vuejs 实战:开发知乎 (2)用户注册
1.本节需要发送验证邮件 2.教程使用SendCloud发送邮件 [我使用的是mailtrap] 3. composer require laravel/ui 安装完成后 php artisan ui ...
- 【MySQL】安装及配置
" 目录 #. 概述 1. 什么是数据(Data) 2. 什么是数据库(DataBase, 简称DB) 3. 什么是数据库管理系统(DataBase Management System) 4 ...
- 安卓之文本视图TextView及跑马灯效果
一.基本属性和设置方法 二.跑马灯用到的属性与方法说明 三.省略方式的取值说明 四.跑马灯效果案例代码 (1)布局xml文件 <?xml version="1.0" en ...
- mysql 单表批量备份sh文件
#!/bin/bashDBS=$(mysql -u root -padmin -e 'use database; show tables;' | awk '{ print $1 }');for tab ...
- Jmeter进行分布式性能测试
由于Jmeter本身的瓶颈,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至还会引起JAVA内存溢出的错误.要解决这个问题,可以使用分布式测试,运行多台机器运行所谓的 ...
- 「AT4741 [ABC132D] Blue and Red Balls」
题目大意 给出一个长度为 \(N\) 的01串,其中有 \(K\) 个 \(1\),其他都是 \(0\),需要求出当着 \(K\) 个 \(1\) 分成 \(1\) 到 \(K\) 段每一个的方案数. ...