AVL树(自平衡二叉查找树)
了解AVL树之前要先了解二叉查找树(BST),BST查找元素的时间复杂度平均是O(logN),最坏的情况是O(N),所有的元素都接在左子树(或者右子树)就相当于一串链表了。而AVL树会对子树过高的情况进行优化,这里有个平衡因子的概念,当前节点的平衡因子=左子树高度-右子树高度,AVL树的每一个节点的平衡因子的绝对值都是 < 2 的。
当一个新节点插入AVL树 ( 根节点为tree ) 的时候会有四种情况:
假设距离新节点最近的失衡节点为 t ( 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树(自平衡二叉查找树)的更多相关文章
- AVL树(平衡二叉查找树)
首先要说AVL树,我们就必须先说二叉查找树,先介绍二叉查找树的一些特性,然后我们再来说平衡树的一些特性,结合这些特性,然后来介绍AVL树. 一.二叉查找树 1.二叉树查找树的相关特征定义 二叉树查找树 ...
- 判断AVL树是否平衡
AVL树是高度的平衡二插搜索树,其左子树和右子树的高度之差不超过1(树中的左子树和右子树都是AVL树),维持这个高度之差就要控制它的平衡因子.那么判断一颗AVL树是否平衡就需要判断它的左子树和右子树高 ...
- AVL树 高度平衡的二叉查找树
1.What is AVL tree? AVL tree 是一种特殊的二叉查找树,,首先我们要在树中引入平衡因子balance,表示结点右子树的高度减去左子树的高度差(右-左),对于一棵AVL树要么它 ...
- AVL树 & 重平衡概念
AVL树是有平衡条件的二叉搜索树.这个平衡条件必须容易保持,而且需要保证树的深度是O(logN). AVL=BBST 作为二叉搜索树的最后一部分,我们来介绍最为经典的一种平衡二叉搜索树:AVL树.回顾 ...
- AVL树的平衡算法(JAVA实现)
1.概念: AVL树本质上还是一个二叉搜索树,不过比二叉搜索树多了一个平衡条件:每个节点的左右子树的高度差不大于1. 二叉树的应用是为了弥补链表的查询效率问题,但是极端情况下,二叉搜索树会无限接近 ...
- 二叉树之AVL树的平衡实现(递归与非递归)
这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...
- AVL树、红黑树以及B树介绍
简介 首先,说一下在数据结构中为什么要引入树这种结构,在我们上篇文章中介绍的数组与链表中,可以发现,数组适合查询这种静态操作(O(1)),不合适删除与插入这种动态操作(O(n)),而链表则是适合删除与 ...
- 深入浅出数据结构C语言版(12)——平衡二叉查找树之AVL树
在上一篇博文中我们提到了,如果对普通二叉查找树进行随机的插入.删除,很可能导致树的严重不平衡 所以这一次,我们就来介绍一种最老的.可以实现左右子树"平衡效果"的树(或者说算法),即 ...
- 006-数据结构-树形结构-二叉树、二叉查找树、平衡二叉查找树-AVL树
一.概述 树其实就是不包含回路的连通无向图.树其实是范畴更广的图的特例. 树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合. 1.1.树的特性: 每个结点有零个或多个子 ...
- 二叉查找树(BST)、平衡二叉树(AVL树)(只有插入说明)
二叉查找树(BST).平衡二叉树(AVL树)(只有插入说明) 二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点, ...
随机推荐
- Protocol_ISIS
集成ISIS协议 作者:Danbo 2015-7-5 ISIS的意思是表示中间系统,并且是为OSI无连接网络协议(OSI Conectionless Network Protocol,CLNP)设计的 ...
- centos 7 / 6 smokeping安装
官网 值得拥有:http://oss.oetiker.ch/smokeping/doc/reading.en.html 安装依赖包 1 2 yum -y install perl perl-Net-T ...
- Android应用资源---动画资源(Animation Resources)
有两种类型的动画资源: 属性动画 在设定的时间内,通过修改与Animator类相关的对象的属性值来创建一个动画. 视图动画 有两种类型的视图动画框架 补间动画(Tween animation):通过执 ...
- multi_socket
threading_test.py #threading #为什么在命令行可以执行,F5不能执行 #线程处理能导致同步问题 from socketserver import TCPServer,Thr ...
- codevs 1147 排座椅
传送门 题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接 ...
- 《Objective-C高级编程》の内存管理の学习笔记
此日志用于记录下学习过程中碰到的问题 转载请注明出处: http://www.cnblogs.com/xdxer/p/4069650.html <Objective-C高级编程> 人民邮电 ...
- web.xml中load-on-startup的作用,web应用写一个InitServlet,这个servlet配置为启动时装载
如下一段配置,熟悉DWR的再熟悉不过了:<servlet> <servlet-name>dwr-invoker</servlet-name> <ser ...
- js的一些刷新功能
<a href="javascript:location.replace(location.href);" title="刷新"> </a&g ...
- HDU-2553
N皇后问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 利用python数据分析panda学习笔记之DataFrame
2 DataFrame a:通过传入一个等长的列表构成DataFrame 自动加上索引 data={'state':['ohio','ohio','ohio','Nevada','Nevada'], ...