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- ...
随机推荐
- 记录STM32调试
问题:加入红外初始化后,程序卡在红外初始化处 解决思路: 1.确认时钟是不是好的 2.把定时器分解调试(输入捕获.溢出分开一步一步弄) 已解决:定时器的溢出中断 注意:STM32Cube配置好后,需要 ...
- cs/bs
c(客户端)/s服务器:使用前必须安装,更新是,c s同时更新,不能跨频繁太,采用自由协议,相对来说安全. b(浏览器)/s:本质上还是cs ,只是使用了浏览器:如京东,淘宝.无需安装,客户端不需要更 ...
- centos7.5下安装jenkins
最近从头搭建了一套python+selenium+pytest+allure+Jenkins的环境,虽然网上挺多的,不过还是记录下来,毕竟坑还是挺多的....... 先从搭建jenkins开始把! 方 ...
- 计算机二级-C语言-对二维数组数据进行处理。对文件进行数据输入。形参与实参。
//函数fun的功能为:计算x所指数组中N个数的平均值(规定所有数都为正数),平均值通过形参返回给主函数,将小于平均值且最接近平均值的数作为函数值返回,并输出. //重难点:形参与实参之间,是否进行了 ...
- ax绘图相关的知识点
1.去边框 # 去掉上.下.左.右边框 ax.spines['top'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.sp ...
- @Primary 注解的作用
当一个接口有两个实现类时,并两个实现类都被 Spring 管理,则需要对某个类进行 @Primary 注解,表示优先选择此实现类. 否则会抛出 异常 org.springframework.beans ...
- socket实现简单的FTP
一.开发环境 server端:centos 7 python-3.6.2 客户端:Windows 7 python-3.6.2 pycharm-2018 程序目的:1.学习使用socketserve ...
- 利用graphviz软件和pycallgraph库自动生成Python代码函数调用关系图
参考博文:https://blog.csdn.net/qq_36408085/article/details/82952846 https://blog.csdn.net/fondax/article ...
- 李彦宏AI大会现场:3秒钟事故30分钟专注
编辑 | 于斌 出品 | 于见(mpyujian) 很多人只看到了舞台上3秒钟的事故,却没有看到李彦宏在台上30分钟的专注. 7月3号,百度AI开发者大会上,李彦宏遭遇了3秒钟的突然袭击,他表现的沉着 ...
- Mac终端ls颜色设置
mac自带的终端是款非常好用的ssh工具,但ls命令下文件与文件夹都是单一的颜色,为了更好区分,作出修改. 终端默认背景颜色为白色,(终端->偏好设置->描述文本),可修改背景颜色与字体大 ...