AVL树(自平衡二叉查找树)

时间:2022-06-07 00:40:11

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

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

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

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

AVL树(自平衡二叉查找树)

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

AVL树(自平衡二叉查找树)

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

AVL树(自平衡二叉查找树)

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

AVL树(自平衡二叉查找树)

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树 &amp&semi; 重平衡概念

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

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

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

  6. 二叉树之AVL树的平衡实现&lpar;递归与非递归&rpar;

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

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

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

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

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

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

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

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

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

随机推荐

  1. HTML中上传与读取图片或文件(input file)----在路上(25)

    input file相关知识简例 在此介绍的input file相关知识为: 上传照片及文件,其中包括单次上传.批量上传.删除照片.增加照片.读取图片.对上传的图片或文件的判断,比如限制图片的张数.限 ...

  2. Oracle 取随机数

    1.从表中随机取记录 select * from (select * from staff order by dbms_random.random)      where rownum < 4 ...

  3. const

     const int i = 20; int const i = 20; 这两个语句是完全相同的:const与int哪个写在前面都不影响语义. 所以: const int *p; int const ...

  4. LVS简单实现NAT&amp&semi;DR模型

    LVS:Linux Virtual Server  一个由章文嵩博士发起的*软件项目,它的官方站点是www.linuxvirtualserver.org. 现在LVS已经是Linux标准内核的一部分 ...

  5. 冒泡排序:一百以内十个随机数放入数组排序并打印&lt&semi;

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. jq 的连续动画

    var direction='right'; (function(){ var css={ 'left':'398px' }; if(direction==='right'){ direction=' ...

  7. &lbrack;置顶&rsqb; 自己动手写Web容器之TomJetty之六:动态页面引入

    传送门 ☞ 1.Web服务内功经脉 传送门 ☞ 2.让服务动起来 传送门 ☞ 3.掀起请求盖头来 传送门 ☞ 4.静态页面起步 传送门 ☞ 5.包装请求参数 在上一节,我们已经完成了TomJetty服 ...

  8. 友坚恒天&period;开发板(Cotex-A9 Exynos4412 开发板)

    友坚恒天.开发板 Cotex-A9 Exynos4412 开发板

  9. Spring &lpar;三&rpar;

    1.1 Spring的事务管理 1.1.1事务 事务:指的是逻辑上一组操作,要么全部成功,要么全部失败. 事务特性: 原子性:事务不可分割. 一致性:事务执行前后,数据完整性保存一致. 隔离性:一个事 ...

  10. MySQL 中添加列、修改列以及删除列

    ALTER TABLE:添加,修改,删除表的列,约束等表的定义. 查看列:desc 表名; 修改表名:alter table t_book rename to bbb; 添加列:); 删除列:alte ...