AVL树是一种自平衡(Self-balancing)二叉查找树(Binary Search Tree),要求任何一个节点的左子树和右子树的高度之差不能超过1。

AVL树的插入操作首先会按照普通二叉查找树的插入操作进行,不同的是在成功插入一个节点后会向上进行回溯,判断路径中的每一个节点左子树和右子树高度之差,如果相差大于1,则进行旋转操作使得树重新达到平衡状态,旋转的本质其实是为当前不平衡的子树选择一个新的根节点,以降低两侧的高度差。

这里以root表示不平衡节点(左右子树高度差大于1),旋转操作可分为以下四种:

  • 右旋转:当加入的节点在root的左子节点的左子树中(LL),以root为轴进行一次右旋转。
  • 左旋转:当加入的节点在root的右子节点的右子树中(RR),以root为轴进行一次左旋转。
  • 左右旋转:当加入的节点在root的左子节点的右子树中(LR),先以root的左子节点为轴进行一次左旋转,再以root为轴进行一次右旋转。
  • 右左旋转:当加入的节点在root的右子节点的左子树中(RL),先以root的右子节点为轴进行一次右旋转,再以root为轴进行一次左旋转。

代码如下:

#include <cstdio>
#include <cstdlib>
#define max(x, y) (((x) > (y)) ? (x) : (y))
typedef struct tnode
{
int val;
struct tnode * left;
struct tnode * right;
} node; //LL:右旋转
node * rotate_right(node * root) {
node * lnode = root->left;
root->left = lnode->right;
lnode->right = root;
return lnode;
} //RR:左旋转
node * rotate_left(node * root) {
node * rnode = root->right;
root->right = rnode->left;
rnode->left = root;
return rnode;
} //LR:先左旋转,再右旋转
node * rotate_left_right(node * root) {
root->left = rotate_left(root->left);
return rotate_right(root);
} //RL:先右旋转,再左旋转
node * rotate_right_left(node * root) {
root->right = rotate_right(root->right);
return rotate_left(root);
} //递归求得以root为根节点的树的高度
int get_height(node * root) {
if (root == NULL) return 0;
return max(get_height(root->left), get_height(root->right)) + 1;
} //在以root为根节点的树中插入值为val的节点
node * insert(node * root, int val) {
if (root == NULL) {
root = (node *) malloc(sizeof(node));
root->val = val;
root->left = NULL;
root->right = NULL;
} else if (val < root->val) {
root->left = insert(root->left, val);
if (get_height(root->left) - get_height(root->right) == 2) {
if (val < root->left->val) root = rotate_right(root);
else root = rotate_left_right(root);
}
} else {
root->right = insert(root->right, val);
if (get_height(root->right) - get_height(root->left) == 2) {
if (val > root->right->val) root = rotate_left(root);
else root = rotate_right_left(root);
}
} return root;
} int main(void) {
int n, val;
node * root = NULL; scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &val);
root = insert(root, val);
} return 0;
}

AVL树的创建--C语言实现的更多相关文章

  1. 数据结构--Avl树的创建,插入的递归版本和非递归版本,删除等操作

    AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树.   2.带有平衡条件:每个结点的左右子树的高度之差的绝对值最多为1(空树的高度为-1).   也就是说,AVL树,本质上 ...

  2. 数据结构与算法(九):AVL树详细讲解

    数据结构与算法(一):基础简介 数据结构与算法(二):基于数组的实现ArrayList源码彻底分析 数据结构与算法(三):基于链表的实现LinkedList源码彻底分析 数据结构与算法(四):基于哈希 ...

  3. 二叉查找树(BST)、平衡二叉树(AVL树)(只有插入说明)

    二叉查找树(BST).平衡二叉树(AVL树)(只有插入说明) 二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点, ...

  4. 二叉查找树(BST)、平衡二叉树(AVL树)

    二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点,都满足其左子树上所有结点的数据域均小于或等于根结点的数据域,右 ...

  5. AVL树原理及实现(C语言实现以及Java语言实现)

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. AVL定义 AVL树是一种改进版的搜索二叉树.对于一般的搜索二叉树而言,如果数据恰好 ...

  6. AVL树(一)之 图文解析 和 C语言的实现

    概要 本章介绍AVL树.和前面介绍"二叉查找树"的流程一样,本章先对AVL树的理论知识进行简单介绍,然后给出C语言的实现.本篇实现的二叉查找树是C语言版的,后面章节再分别给出C++ ...

  7. AVL树(查找、插入、删除)——C语言

    AVL树 平衡二叉查找树(Self-balancing binary search tree)又被称为AVL树(AVL树是根据它的发明者G. M. Adelson-Velskii和E. M. Land ...

  8. Avl树的基本操作(c语言实现)

    #include<stdio.h> #include<stdlib.h> typedef struct AvlNode *Position; typedef struct Av ...

  9. 深入浅出数据结构C语言版(12)——平衡二叉查找树之AVL树

    在上一篇博文中我们提到了,如果对普通二叉查找树进行随机的插入.删除,很可能导致树的严重不平衡 所以这一次,我们就来介绍一种最老的.可以实现左右子树"平衡效果"的树(或者说算法),即 ...

随机推荐

  1. PL/SQL登录Oracle18数据库:ORA-12154:TNS无法解析指定的连接标识符

    PL/SQL登录Oracle18数据库出现ORA-12154:TNS无法解析指定的连接标识符解决以下问题:首先更改Oracle客户端的tnsnames.ora,我的路径是:D:\OracleSQL\n ...

  2. Mybatis自动生成插件对数据库类型为text的处理

    2019独角兽企业重金招聘Python工程师标准>>> 如果数据库中的字段为text或者blob这种大文本类型,在使用MybatisGenerator工具自动生成代码的时候会将其进行 ...

  3. golang 线上项目部署折腾之一

    最近自己使用golang折腾了一点东西,可是需要部署到线上才好玩,那么服务器使用了aws,然后使用了docker和没有使用docker部署了一次.简单记录一下过程 aws服务器 为什么使用aws呢,说 ...

  4. LFS资料和SSH远程登录全过程

    LFS 即 Linux From Scratch, From Scratch的意思是"白手起家",即从0开始安装Linux,它的所有软件包都需要从源代码开始编译安装.这是通过实际动 ...

  5. 网速慢?不!可能是DNS出了问题! 公共DNS优选之 BAT 百度、腾讯、阿里、谷歌DNS哪个更快?

    如果一下还是解决不了你的问题请这边走 首先是Google的DNS: 8.8.8.8 丢包严重 PASS但是扶墙的时候是必备的,如果有扶墙的需求的话可以备用. 二.百度DNS 180.76.76.76 ...

  6. STL训练 HDU - 1716 Ray又对数字的列产生了兴趣:

    HDU - 1716 Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数. Input 每组数据占一行,代表四张卡片上的数字(0&l ...

  7. P4370 [Code+#4]组合数问题2

    题目要求当\(0\leq a\leq b\leq n\)时,\(k\)个\(\tbinom{b}{a}\)的和的最大值 观察杨辉三角形,可以发现,最大的\(\tbinom{b}{a}\),为\(\tb ...

  8. 题目分享E 二代目

    题意:一棵点数为n的树,每个节点有点权,要求在树中中找到一个最小的x,使得存在一个点满足max(该点点权,该点相邻的点的点权+1,其他点的点权+2)=x 分析:首先要能把题目转化为上述题意 首先题目让 ...

  9. 【Hexo】使用Hexo+github pages+travis ci 实现自动化部署

    目录 一.说明 二.成品展示 三.前期准备 本地安装 node.js 本地安装 git github 账号 创建仓库 travis ci 账号 四.安装 Hexo 五.使用 hexo 搭建博客 六.部 ...

  10. WPF客户端自动升级

    实现原理:通过一个辅助程序(更新程序.exe)比较本地版本号和服务器的版本,若服务器版本新则通过更新程序.exe下载服务器上资源(我是把最新的文件压缩成zip放到服务器上)到本地进行替换. 服务器放置 ...