了解AVL树之前要先了解二叉查找树(BST),BST查找元素的时间复杂度平均是O(logN),最坏的情况是O(N),所有的元素都接在左子树(或者右子树)就相当于一串链表了。而AVL树会对子树过高的情况进行优化,这里有个平衡因子的概念,当前节点的平衡因子=左子树高度-右子树高度,AVL树的每一个节点的平衡因子的绝对值都是 < 2 的。

当一个新节点插入AVL树 ( 根节点为tree ) 的时候会有四种情况:

假设距离新节点最近的失衡节点为 t ( 的平衡因子的绝对值达到了2,且距离新节点最近)

1、LL型:新节点在 t1 的左孩子的左子树上,需要对 t 进行一次右旋操作;

2、RR型:新节点在 t 的右孩子的右子树上,需要对 t 进行一次左旋操作;

3、LR型:新节点在 t 的左孩子的右子树上,需要先对 t 的左孩子进行一次RR(左旋)操作,然后对 t 进行一次LL(右旋)操作;

4、RL型:新节点在 t 的右孩子的左子树上,需要先对 t 的右孩子进行一次LL(右旋)操作,然后对 t 进行一次RR(左旋)操作;

AVL树的实现代码如下:

 #include "pch.h"
#include <iostream>
#include <queue>
#define ElementType int//自定义元素类型
using namespace std;
typedef struct node *AVLTree;
struct node {
ElementType key;
int Height = ;
AVLTree left = NULL, right = NULL;
};
int Height(AVLTree tree);//求树的高度
ElementType Max(ElementType a, ElementType b);
AVLTree insert(AVLTree tree, ElementType &key);//在AVLTree中插入节点
AVLTree LL_Rotation(AVLTree tree);//LL旋转
AVLTree RR_Rotation(AVLTree tree);//RR旋转
AVLTree LR_Rotation(AVLTree tree);//LR旋转
AVLTree RL_Rotation(AVLTree tree);//RL旋转 void levelTraversal(AVLTree tree);//层序遍历,用于测试 /*用main函数来测试,给N个不同的数据,插入AVL树中,然后层序输出*/
int main()
{
int N;
ElementType key;
AVLTree tree = NULL;
scanf("%d", &N);
for (int i = ; i < N; i++) {
cin >> key;
tree = insert(tree, key);
}
levelTraversal(tree);
} AVLTree insert(AVLTree tree, ElementType &key) {
if (tree == NULL) {
tree = new node();
tree->key = key;
}
else if (key < tree->key) {
tree->left = insert(tree->left, key);//key小于当前节点的值时继续往其左子树递归地插入
if (Height(tree->left) - Height(tree->right) >= ) {//左子树与右子树的高度差达到2的时候就要对当前节点进行旋转,这里由于是递归地执行,保证了平衡因子达到2的节点是最接近插入点的
if (key < tree->left->key)
tree = LL_Rotation(tree);
else
tree = LR_Rotation(tree);
}
}
else {
tree->right = insert(tree->right, key);
if (Height(tree->right) - Height(tree->left) >= ) {
if (key > tree->right->key)
tree = RR_Rotation(tree);
else
tree = RL_Rotation(tree);
}
}
tree->Height = Max(Height(tree->left), Height(tree->right)) + ;//当前节点的高度为其最大子树的高度+1
return tree;
} AVLTree LR_Rotation(AVLTree tree) {
tree->left = RR_Rotation(tree->left);
return LL_Rotation(tree);
} AVLTree RL_Rotation(AVLTree tree) {
tree->right = LL_Rotation(tree->right);
return RR_Rotation(tree);
} AVLTree RR_Rotation(AVLTree tree) {
AVLTree tree2 = tree->right;
tree->right = tree2->left;
tree2->left = tree;
tree->Height = Max(Height(tree->left), Height(tree->right)) + ;
tree2->Height = Max(Height(tree2->right), tree->Height) + ;
return tree2;
} AVLTree LL_Rotation(AVLTree tree) {
AVLTree tree2 = tree->left;
tree->left = tree2->right;
tree2->right = tree;
tree->Height = Max(Height(tree->left), Height(tree->right)) + ;
tree2->Height = Max(Height(tree->left), tree->Height) + ;
return tree2;
} int Height(AVLTree tree) {
if (tree == NULL)
return ;
return tree->Height;
} ElementType Max(ElementType a, ElementType b) {
return a > b ? a : b;
} void levelTraversal(AVLTree tree)
{
queue <AVLTree> Q;
Q.push(tree);
while (!Q.empty()) {
AVLTree t = Q.front();
Q.pop();
cout << t->key << " ";
if (t->left != NULL)
Q.push(t->left);
if (t->right != NULL)
Q.push(t->right);
}
}

AVL树(自平衡二叉查找树)的更多相关文章

  1. AVL树(平衡二叉查找树)

    首先要说AVL树,我们就必须先说二叉查找树,先介绍二叉查找树的一些特性,然后我们再来说平衡树的一些特性,结合这些特性,然后来介绍AVL树. 一.二叉查找树 1.二叉树查找树的相关特征定义 二叉树查找树 ...

  2. 判断AVL树是否平衡

    AVL树是高度的平衡二插搜索树,其左子树和右子树的高度之差不超过1(树中的左子树和右子树都是AVL树),维持这个高度之差就要控制它的平衡因子.那么判断一颗AVL树是否平衡就需要判断它的左子树和右子树高 ...

  3. AVL树 高度平衡的二叉查找树

    1.What is AVL tree? AVL tree 是一种特殊的二叉查找树,,首先我们要在树中引入平衡因子balance,表示结点右子树的高度减去左子树的高度差(右-左),对于一棵AVL树要么它 ...

  4. AVL树 & 重平衡概念

    AVL树是有平衡条件的二叉搜索树.这个平衡条件必须容易保持,而且需要保证树的深度是O(logN). AVL=BBST 作为二叉搜索树的最后一部分,我们来介绍最为经典的一种平衡二叉搜索树:AVL树.回顾 ...

  5. AVL树的平衡算法(JAVA实现)

      1.概念: AVL树本质上还是一个二叉搜索树,不过比二叉搜索树多了一个平衡条件:每个节点的左右子树的高度差不大于1. 二叉树的应用是为了弥补链表的查询效率问题,但是极端情况下,二叉搜索树会无限接近 ...

  6. 二叉树之AVL树的平衡实现(递归与非递归)

    这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...

  7. AVL树、红黑树以及B树介绍

    简介 首先,说一下在数据结构中为什么要引入树这种结构,在我们上篇文章中介绍的数组与链表中,可以发现,数组适合查询这种静态操作(O(1)),不合适删除与插入这种动态操作(O(n)),而链表则是适合删除与 ...

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

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

  9. 006-数据结构-树形结构-二叉树、二叉查找树、平衡二叉查找树-AVL树

    一.概述 树其实就是不包含回路的连通无向图.树其实是范畴更广的图的特例. 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合. 1.1.树的特性: 每个结点有零个或多个子 ...

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

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

随机推荐

  1. Debug 和 Release 的区别

    Debug 和 Release 的区别         Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程 ...

  2. JS中奇葩的假值

    JavaScript中有 6 个值为“假”,这六个值是 false null undefined 0 '' (空字符串) NaN 这里面 false 本身是布尔类型,其它 5 个则不是. 除了这 6 ...

  3. ubuntu搭建ftp

    腾讯云服务器linux Ubuntu操作系统安装ftp服务器vsftpd Ubuntu Server 16.04.1 LTS 64位 登录服务器  xshell 登录服务器 用户名如果没自定义默认:u ...

  4. 关于“telnet localhost:8080不能打开到主机的连接, 在端口 23: 连接失败”问题

    你的命令写错了!不是telnet localhost:1433 是 telnet localhost 1433 不要那个:号 http://www.fengfly.com/ 答案补充 :“正在连接到l ...

  5. python 实用pickle序列化

    存储数据结构到一个文件中称为序列化.相json这样的格式需要定制的序列化数据的转换器.python提供了pickle模块以特殊的二进制格式保存和恢复数据对象. 还记得json解析datetime对象时 ...

  6. Android工程的目录结构

    1.最大限度的将不需要出现在Java代码中的文件和代码本身分离开来 2.使用XML标记语言定义UI和数据结构 3.对于工程中的文件存储在工程目录中的那个位置有着严格的规定,在编译过程中Android会 ...

  7. python 基础之第五天

    ###########window路径写法########## In [1]: winpath = 'C:\tmp' In [2]: print winpath C: mp In [3]: winpa ...

  8. [ZJOI 2007] 捉迷藏

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1095 [算法] 首先建出点分树,然后每一个点开两个堆.“第一个堆记录子树中所有节点到 ...

  9. robotium

    Test run failed: Permission Denial: starting instrumentation ComponentInfo{android.support.v7.appcom ...

  10. Linux系统如何查看版本信息?

    查看版本号 我在Ubuntu下做测试 1 命令行执行 cat /etc/issue  (切记cat后要空一格)即可看到版本信息. 2 登录linux,在终端输入 cat /proc/version  ...