数据结构——平衡二叉树(AVLTree)
3.平衡二叉树
平衡二叉树,又称AVL树,它是一种特殊的二叉排序树。
3.1 平衡二叉树的四种自旋
这个左旋、右旋,在方向上和我观念里的是相反的。
查了之后才知道:
1、外侧插入:LL、RR,都是在最边边上。
2、内侧插入:LR、RL,往里面来了些。

(1)LL旋转和RR旋转:

void RR_Rotate(AVLTree *root){
AVLTreeNode* rchild = (*root)->Right;
(*root)->Right = rchild->Left;
rchild->Left = *root;
*root = rchild;
}
void LL_Rotate(AVLTree *root) {
AVLTreeNode* lchild = (*root)->Left;
(*root)->Left = lchild->Right;
lchild->Right = *root;
*root = lchild;
}
(2)LR,RL型旋转(插入的节点在CL上 还是CR上是没有影响的)

LR型旋转图解

void LR_Rotate(AVLTree *root) {
RR_Rotate(&(*root)->Left);
return LL_Rotate(root);
}
void RL_Rotate(AVLTree *root) {
LL_Rotate(&(*root)->Right);
RR_Rotate(root);
}
小结:几个子树在水平位置上顺序是不会变的!根节点和根节点的子树在水平上的逻辑位置也是不会变的。
3.2 平衡二叉树的插入
插入算法就是出现不平衡状态时,判断需要使用哪种旋转方式来使得二叉树保持平衡:
AVLTree InsertAVLTree(AVLTree root, int x) {
if (root == NULL) {
root = new AVLTreeNode;
root->Left = NULL;
root->Right = NULL;
root->data = x;
return root;
}
if (x > root->data) {
root->Right = InsertAVLTree(root->Right, x);
//递归返回插入位置的父节点或者祖父……,如果失去了平衡
) {
//如果插入的值大于,当前节点的左孩子节点,说明该节点是插在root的右子树上的
if (x > root->Left->data) RR_Rotate(&root);
else RL_Rotate(&root);
}
}
else if (x < root->data) {
root->Left = InsertAVLTree(root->Left, x);
) {
if (x < root->Left->data) LL_Rotate(&root);
else LR_Rotate(&root);
}
}
else {
cout << "the number is already included." << endl;
return NULL;
}
return root;
}
3.3 平衡二叉树的删除
之前写过二叉排序树的节点的删除的话,这里会好写很多,就是多出来一个判断从哪个子树删除节点的问题。
void AVLTreeDel(AVLTree *root, int data)
{
if (!*root) {
cout << "delete failed" << endl;
return;
}
AVLTreeNode *p = *root;
if (data == p->data) {
//左右子树都非空
if (p->Left && p->Right) {
//在高度更大的那个子树上进行删除操作
//进左子树,右转到底,进右子树,左转到底,转弯碰壁,杀孩子。
if (height(p->Left) > height(p->Right)) {
AVLTreeNode *pre=NULL,*q = p->Left;
if (!q->Right)
q->Right = p->Right;
else {
while (q->Right) {
pre = q;
q = q->Right;
}
pre->Right = q->Left;
q->Left = p->Left;
q->Right = p->Right;
}
*root = q;
}
else {
AVLTreeNode *pre = NULL, *q = p->Right;
if (!q->Left)
q->Left = p->Left;
else {
while (q->Left) {
pre = q;
q = q->Left;
}
pre->Left = q->Right;
q->Left = p->Left;
q->Right = p->Right;
}
*root=q;
}
}
else
(*root) = (*root)->Left ? (*root)->Left : (*root)->Right;
delete p;
}
else if (data < p->data){//要删除的节点在左子树中
//在左子树中进行递归删除
AVLTreeDel(&(*root)->Left, data);
//判断是否仍然满足平衡条件
){
//如果当前节点右孩子的左子树更高
if (height(p->Right->Left) > height(p->Right->Right))
RL_Rotate(root);
else
RR_Rotate(root);
}
}
else{
AVLTreeDel(&(*root)->Right, data);
) {
if (height((*root)->Left->Left) > height((*root)->Left->Right))
LL_Rotate(root);
else
LR_Rotate(root);
}
}
}
https://www.2cto.com/kf/201702/556250.html
完整代码(2019.1.20):
#pragma once
#include "top.h"
typedef BTreeNode AVLTreeNode, *AVLTree;
void RR_Rotate(AVLTree *root){
AVLTreeNode* Right = (*root)->Right;
(*root)->Right = Right->Left;
Right->Left = *root;
*root = Right;
}
void LL_Rotate(AVLTree *root) {
AVLTreeNode* Left = (*root)->Left;
(*root)->Left = Left->Right;
Left->Right = *root;
*root = Left;
}
void LR_Rotate(AVLTree *root) {
RR_Rotate(&(*root)->Left);
return LL_Rotate(root);
}
void RL_Rotate(AVLTree *root) {
LL_Rotate(&(*root)->Right);
RR_Rotate(root);
}
AVLTree AVLTreeInsert(AVLTree root, int x) {
if (root == NULL) {
root = new AVLTreeNode;
root->Left = NULL;
root->Right = NULL;
root->data = x;
return root;
}
if (x > root->data) {
root->Right = AVLTreeInsert(root->Right, x);
//递归返回插入位置的父节点或者祖父……,如果失去了平衡
) {
//如果插入的值大于,当前节点的右孩子节点,说明该节点是插在root的右子树上的
//if (x > root->Left->data) RR_Rotate(&root);不能保证该节点一定有左子树
if (x > root->Right->data)RR_Rotate(&root);
else RL_Rotate(&root);
}
}
else if (x < root->data) {
root->Left = AVLTreeInsert(root->Left, x);
) {
if (x < root->Left->data) LL_Rotate(&root);
else LR_Rotate(&root);
}
}
else {
cout << "the number is already included." << endl;
return NULL;
}
return root;
}
AVLTree AVLTreeCreat(int *a, int length) {
AVLTree T = NULL;
; i < length; i++) {
T = AVLTreeInsert(T, a[i]);
}
return T;
}
AVLTreeNode* AVLFind(AVLTree T, int x) {
AVLTreeNode *p = T;
while (p) {
if (x == p->data) break;
p = x > p->data ? p->Right : p->Left;
}
return p;
}
AVLTree AVLMax(AVLTree p)
{
if (!p) return NULL;
if (p->Right == NULL)
return p;
return AVLMax(p->Right);
}
AVLTree AVLMin(AVLTree p)
{
if (!p)
return NULL;
if (p->Left == NULL)
return p;
return AVLMin(p->Left);
}
void AVLTreeDel(AVLTree *root, int data)
{
if (!*root) {
cout << "delete failed" << endl;
return;
}
AVLTreeNode *p = *root;
if (data == p->data) {
//左右子树都非空
if (p->Left && p->Right) {
//在高度更大的那个子树上进行删除操作
//进左子树,右转到底,进右子树,左转到底,转弯碰壁,杀孩子。
if (height(p->Left) > height(p->Right)) {
AVLTreeNode *pre=NULL,*q = p->Left;
if (!q->Right)
q->Right = p->Right;
else {
while (q->Right) {
pre = q;
q = q->Right;
}
pre->Right = q->Left;
q->Left = p->Left;
q->Right = p->Right;
}
*root = q;
}
else {
AVLTreeNode *pre = NULL, *q = p->Right;
if (!q->Left)
q->Left = p->Left;
else {
while (q->Left) {
pre = q;
q = q->Left;
}
pre->Left = q->Right;
q->Left = p->Left;
q->Right = p->Right;
}
*root=q;
}
}
else
(*root) = (*root)->Left ? (*root)->Left : (*root)->Right;
delete p;
}
else if (data < p->data){//要删除的节点在左子树中
//在左子树中进行递归删除
AVLTreeDel(&(*root)->Left, data);
//判断是否仍然满足平衡条件
){
//如果当前节点右孩子的左子树更高
if (height(p->Right->Left) > height(p->Right->Right))
RL_Rotate(root);
else
RR_Rotate(root);
}
}
else{
AVLTreeDel(&(*root)->Right, data);
) {
if (height((*root)->Left->Left) > height((*root)->Left->Right))
LL_Rotate(root);
else
LR_Rotate(root);
}
}
}
void checkCreat() {
;
);
; i < length; i++) {
cout << a[i] << ",";
}
cout << endl;
AVLTree T = AVLTreeCreat(a, length);
int t = rand() % length;
AVLTreeDel(&T, a[t]);
; i++) {
a[i] = a[i + ];
}
Preorder(T);
cout << endl;
Inorder(T);
cout << endl;
Postorder(T);
cout << endl;
free(a);
}
数据结构——平衡二叉树(AVLTree)的更多相关文章
- 什么是泛型?,Set集合,TreeSet集合自然排序和比较器排序,数据结构-二叉树,数据结构-平衡二叉树
==知识点== 1.泛型 2.Set集合 3.TreeSet 4.数据结构-二叉树 5.数据结构-平衡二叉树 ==用到的单词== 1.element[ˈelɪmənt] 要素 元素(软) 2.key[ ...
- 数据结构-平衡二叉树 旋转过程平衡因子分析 c和java代码实现对比
平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且 ...
- java——平衡二叉树 AVLTree、AVLMap、AVLSet
平衡二叉树:对于任意一个节点,左子树和右子树的高度差不能超过1 package Date_pacage; import java.util.ArrayList; public class AVLTre ...
- 平衡二叉树(AVLTREE,双链表实现)
首先说下好久没更新了,最近打游戏和工作都有点多,o(^▽^)o. 写这个AVL发现自己的代码风格好差,尤其是变量命名这块,后来意识到了,想去改,但是太多了,改了几个就不想改了,做这个是记录下自己的成长 ...
- Java数据结构——平衡二叉树的平衡因子(转自牛客网)
若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性.首先要找出插入新结点后失去平衡的最小子树根结点的指针.然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树.当失去平衡的最小子树被 ...
- 大话数据结构—平衡二叉树(AVL树)
平衡二叉树(Self-Balancing Binary Search Tree/Height-Balanced Binary Search Tree),是一种二叉排序树,当中每个节点的左子树和右子树的 ...
- 数据结构-平衡二叉树Java实现
1,Node.java package com.cnblogs.mufasa.BalanceBinaryTree; public class Node { Node parent; Node left ...
- JavaScript数据结构——树的实现
在计算机科学中,树是一种十分重要的数据结构.树被描述为一种分层数据抽象模型,常用来描述数据间的层级关系和组织结构.树也是一种非顺序的数据结构.下图展示了树的定义: 在介绍如何用JavaScript实现 ...
- 20162325 金立清 S2 W8 C17
20162325 2017-2018-2 <程序设计与数据结构>第8周学习总结 教材学习内容概要 二叉查找树是一棵二叉树,对于其中的每个结点,左子树上的元素小于父结点的值,而右子树上的元素 ...
随机推荐
- ubuntu16.04 安装 nginx 服务器
在线安装 apt-get install nginx 说明 启动程序文件在/usr/sbin/nginx 日志放在了/var/log/nginx中,分别是access.log和error.log 并已 ...
- C#图片验证码绘制
制作验证码.也可以画弧线之类..... //新建一个网站,在后台代码中引用一个using Stystem.Drawing的命名空间 Bitmap img = , ); //制作一个宽100,高50的画 ...
- 设置placeholder的字体颜色
//设置字体颜色 [self.searchTextField setValue:[UIColor colorWithRed:0.50 green:0.50 blue:0.50 alpha:1.0] f ...
- CODEFORCES 429B 动态规划
http://codeforces.com/problemset/problem/429/B 可以参考这篇文章: http://blog.csdn.net/pure_lady/article/deta ...
- spss C# 二次开发 学习笔记(三)——Spss .Net 开发
Spss .Net 二次开发的学习过程暂停了一段时间,今天开始重启. 之前脑残的不得了,本想从网上下载一个Spss的安装包,然后安装学习.于是百度搜索Spss,在百度搜索框的列表中看到Spss17.S ...
- 原生javascript实现类似jquery on方法的行为监听
原生javascript有addEventListener和attachEvent方法来注册事件,但有时候我们需要判断某一行为甚至某一函数是否被执行了,并且能够获取前一行为的参数,这个时候就需要其他方 ...
- 如何用Fireworks制作经典的扫光字GIF动画
1.首先我们把背景选为黑色.再输入文字用白色填充,注意调整文字之间的间隔. 2.选中字体,对其进行转换为路径文件. 3.对间隔再做少许调整. 4.复制文字改为黑色,做平移,出现立体效果. 5.再复制一 ...
- GIS平台结构设计
前言: WebGIS由于技术发展和功能定位的原因,一般在进行架构设计的时候更多地考虑是否容易实现.用户交互.数据传输方便.渲染效果等方面,对强GIS的应用考虑得少,所以架构上与桌面的GIS平台很不一样 ...
- Wasserstein GAN最新进展:从weight clipping到gradient penalty,更加先进的Lipschitz限制手法
前段时间,Wasserstein GAN以其精巧的理论分析.简单至极的算法实现.出色的实验效果,在GAN研究圈内掀起了一阵热潮(对WGAN不熟悉的读者,可以参考我之前写的介绍文章:令人拍案叫绝的Was ...
- Get a “step-by-step” evaluation in Mathematica
Is it possible in Mathematica to get a step-by-step evaluation of some functions; that's to say, out ...