AVL平衡调整步骤:
代码写的十分潦草而且没经过测试,看个乐,我认为应该重点看一下没有parent指针的版本,以及我认为这里重点在于理解过程。

  1. 插入结点

  2. 找到 插入节点的 的第一个 不平衡的 非父祖先结点
    2.1 循环遍历插入结点的祖先结点
    2.2 在遍历的同时判断该结点是否平衡
    2.3 平衡则更新当前结点的高度,为了下一次判断是否平衡,不平衡则进行平衡调整

  3. 平衡则进行平衡调整
    3.1 判断三个结点的位置关系(LL,RR,LR,RL)
    3.2 进行平衡
    3.3 维护结点指针
    如果是删除导致的结点失衡,在afteradd里把break去掉就可以,一直往上查找是否导致了新的祖先结点失衡,反复平衡
    而且无论是添加导致的失衡,还是删除导致的失衡,修复的过程都是找到失衡结点进行旋转,旋转的过程也是一样的,找两个更高的子树结点,判断LL,RR,进行调整
    更详细的也可以看看别人写的笔记
    !!!

****我犯的错误::有没有可能旋转涉及的三个结点不连在一起? 不可能
有没有可能LL RR LR RL之外的情况?? 不可能 ****
需要注意:旋转中涉及到的三个结点分别是:第一个失衡非父祖先结点,第一个失衡非父祖先结点的左子结点或右子结点,第一个失衡非父祖先结点的左子结点或右子结点的左子结点或右子结点
也就是说,我们旋转这个操作是针对失衡的那个祖先结点,涉及了三个连在一起的结点,而这三个结点不一定是插入结点本身也不一定是插入结点的父结点(除非插入结点和父结点就是和失衡结点连在一起的那种最简单结构),我初学时总是觉得这三个点可能不在一起,实际上是混淆了平衡调整的目的是对失衡那个结点的调整,而不一定是对插入结点处,因为插入结点可能本身在很大一颗平衡的AVL子树中。
所以旋转的结点是三个相连的结点,自然只有这四种情况

//!二叉搜索树的添加删除,搜索操作的时间复杂度跟树的高度有关,为O(h)(相比线性表的O(n)搜索以及添加的话)
//! 满二叉树的高度基本是logn,所以满的二叉搜索树的时间复杂度也接近O(logn)
//! 但是如果二叉搜索树建立的顺序,输入是一个有序数组的话,比如1,2,3,4,5,。。。n这样建立的二叉搜索树高度就等于n
//! 也就是最坏时间复杂度等于O(n),被称为二叉搜索树退化为链表
//! 所以我们要尽力维持时间复杂度在O(h)而不是O(n)//! 平衡的概念:二叉树结点数量固定,左右子树高度越接近就越平衡,完全二叉树和满二叉树是最平衡的//! 所以如何改进我们的二叉搜索树??
//! 1.改变添加删除的元素顺序,简介控制树的高度   2.改善添加元素后的二叉树,使之更平衡
//! 我们设计的二叉搜索树是给别人用的,所以添加删除的顺序,我们无法改变,所以我们只能从添加后的二叉树的平衡改进入手
//! 一颗达到适度平衡的二叉搜索树 ,我们称之为平衡二叉搜索树  比如:AVL树,红黑树
//! AVL树是以其发明者命名的,发明者是一个苏联科学家,AVL树是最早发明的自平衡二叉搜索树之—,搜索、添加、删除的时间复杂度是O(logn)O(logn)
//! 平衡因子:该结点平衡因子等于左子树高度减去右子树高度,绝对值小于等于1,即超过1或小于-1,即为失衡,就要自动调整
#include <iostream>
#include "queue"
#include "stack"
#include <string>
#include <algorithm>
using namespace std;
class AVLNode
{public:int element;int height;AVLNode *left;AVLNode *right;AVLNode *parent;AVLNode(){this->element = 0;this->left = nullptr;this->right = nullptr;this->parent = nullptr;this->height = 1;}AVLNode(int element){this->element = element;this->left = nullptr;this->right = nullptr;this->parent = nullptr;this->height = 0;}
};class AVLtreeZH
{private:int size;public://我这里把根节点写成public了,主要后面写一些函数可以方便点AVLNode *root = nullptr;void add(int element); //添加元素void afterAdd(AVLNode *node);         //! 添加后判断是否进行以及高度更新  //平衡步骤//什么时候更新结点高度bool isBalanced(AVLNode *node);       //! 判断一个结点是否平衡int balanceFactor(AVLNode *node);     //! 获取一个结点的平衡因子void balancing(AVLNode *node);        //! 如何判别平衡操作的类型(RR,LL,LR,RL)AVLNode *heigherChild(AVLNode *node); //!  返回左右子树中高度较高的那个子结点int getHeight(AVLNode *node);         //! 通过左右子树的height值,返回当前结点的高度void rotateRight(AVLNode *node1);     //! 以node1右旋void rotateLeft(AVLNode *node1);      //! 以node1左旋
};void AVLtreeZH::afterAdd(AVLNode *node)
{while (node->parent != nullptr){node = node->parent;if (isBalanced(node)){node->height = getHeight(node); //更新结点高度continue;}else{balancing(node);break; //如果是删除导致的结点失衡,这里把break去掉就可以了,一直往上查找是否导致了新的祖先结点失衡}}
}void AVLtreeZH::balancing(AVLNode *node1)
{AVLNode *node2 = heigherChild(node1);AVLNode *node3 = heigherChild(node2);if (node2 == node1->left && node3 == node2->left){ //LL情况rotateRight(node1);}if (node2 == node1->left && node3 == node2->right){ //LR情况rotateLeft(node2);rotateRight(node1);}if (node2 == node1->right && node3 == node2->right){ //RR情况rotateLeft(node1);}if (node2 == node1->right && node3 == node2->left){ //RL情况rotateRight(node2);rotateLeft(node1);}
}void AVLtreeZH::rotateRight(AVLNode *node1)
{AVLNode *node2 = heigherChild(node1);AVLNode *node3 = heigherChild(node2);AVLNode *noderoot = node1->parent;node1->left = node2->right; //核心就这两句node2->right = node1;node1->parent = node2; //维护父结点指针node2->parent = noderoot;if (node1->left != nullptr){node1->left->parent = node1;}if (noderoot == nullptr){}else if (node1 == noderoot->left){node2 = noderoot->left;}else if (node1 == noderoot->right){node2 = noderoot->right;}node1->height = getHeight(node1);node2->height = getHeight(node2);node3->height = getHeight(node3);if (noderoot != nullptr){noderoot->height = getHeight(noderoot);}
}void AVLtreeZH::rotateLeft(AVLNode *node1)
{//和右旋一个路子
}bool AVLtreeZH::isBalanced(AVLNode *node) //判断结点是否平衡,其实就是看平衡因子绝对值有没有大于等于2
{int i = balanceFactor(node);if (i < -1 || i > 1){return false;}else if (-1 <= i <= 1){return true;}
}int AVLtreeZH::getHeight(AVLNode *node)
{if (node->left->height >= node->right->height){return (node->left->height + 1);}else{return (node->right->height + 1);}
}int AVLtreeZH::balanceFactor(AVLNode *node)
{return getHeight(node->left) - getHeight(node->right);
}AVLNode *AVLtreeZH::heigherChild(AVLNode *node)
{int leftheight;int rightheight;if (node->left == nullptr){leftheight = 0;}if (node->right == nullptr){rightheight = 0;}if (leftheight == 0 && rightheight == 0){return nullptr;}if (leftheight > rightheight){return node->left;}else if (leftheight < rightheight){return node->right;}
}

2021- 10 -13 AVL树的平衡调整(有parent指针) 代码逻辑相关推荐

  1. 电动力学每日一题 2021/10/13 用Fourier变换法计算静止电荷产生的电场

    电动力学每日一题 2021/10/13 用Fourier变换法计算静止电荷产生的电场 静止点电荷 具有均匀线密度的静止电荷产生的电场 具有均匀面密度的静止电荷产生的电场 用Fourier变换法计算电场 ...

  2. 2021-10-11 ! AVL树 及其平衡调整 四种情况 恋上数据结构笔记 (考过)

    b站有个up讲的很详细 https://www.bilibili.com/video/BV1xE411h7dd?from=search&seid=11383601726930144190&am ...

  3. 数据结构:AVL树的平衡调整——LL,LR,RL,RR

    AVL树的全称是平衡搜索二叉树,本质上也是一个二叉搜索树(BST),满足BST树的所有性质. 但是我们在使用二叉搜索树的时候,我们知道通常情况在BST中搜索一个节点的时间复杂度是O(lgn). 最坏的 ...

  4. 科恩第一章Friday, October 29, 2021 10:13 AM

    文章目录 Chapeter 1 Part A Electromagnetic Waves and Photons **Wave-particle Duality** Chapeter 1 Friday ...

  5. Bootstrap 响应式开发(2021.10.13)

    目录 一.响应式开发 1.框架含义 2.响应式 3.响应式尺寸划分 二.Bootstrap简介 1.Bootstrap概念 2.查阅Bootstrap文档 3.Bootstrap的使用 (1)创建文件 ...

  6. 2021.10.13会议记录

    根据需求具体内容和讨论补充功能确定平台定位以及可提供服务的设备类型(网页端/移动端). 仍然选择哔哩哔哩直播作为调研对象,对PC端直播进行具体开播流程.直播设置和直播中可操作内容进行具体调研. 针对无 ...

  7. 2021.10.13股票小计

    今天大盘上午低开的意思,不过到了下午稍微有点起色,今天总体是低开高走的状态.证券方面今天整个证券板块涨了0.64个点,华林证券昨天板块大跌的时候涨了,所以今天板块涨的时候没怎么跟涨,收跌1.68个点, ...

  8. 树、二叉树、AVL树,B树基础学习

    树.二叉树.AVL树,B树基础学习 一.树的基本概念 树是一种数据结构,它是由n(n>1)个有限节点组成的一个具有层次关系的集合. 树的基本概念 1.双亲:若有一个结点有子树,那么该结点就称为子 ...

  9. DSA 经典数据结构与算法 学习心得和知识总结(四) | AVL树

    AVL树 从BST的角度看AVL AVL的定义及性质 AVL树的结构定义 AVL树的旋转算法 左左情况---右旋 右右情况---左旋 左右情况---左右旋 右左情况---右左旋 AVL树的遍历操作 A ...

最新文章

  1. centos6编译安装MYSQL8_CentOS 6.4编译安装MySQL8.0
  2. c语言管理系统的数据存放,编的学生成绩管理系统 从文件中读取保存数据总会多读入一组乱码数据...
  3. java 识别手机_java – 如何识别手机闲置?
  4. jvm学习笔记(2)——java对象的内存布局
  5. 阿里巴巴美股股价大跌:创在美上市以来最大单日跌幅
  6. 水系图可以在哪里找_顶刊EES综述:水系锌离子电池面临的问题与机遇
  7. mfc之CPtrArray数组
  8. pandas—dropna
  9. Java计算文件MD5值(支持大文件)
  10. 基于PHP的个人博客系统的设计与开发(含源文件)
  11. 中国电信物联网平台入门学习笔记4:连接时间过长,数据传输消失,电信平台显示延迟...
  12. 乾隆年间贪污贿赂成风:皇帝敛财不逊臣子
  13. 可爱女生开糖果花店,她两年时间就挣了一百万元
  14. 微信订阅号之政府认证
  15. 清华姚班教授:​我见过太多博士生精神崩溃,身体垮掉,一事无成
  16. Java导出多个excel并打包压缩成.zip文件
  17. 【英译中】如何拍好沙滩照1——2014年7月23日
  18. macOS中安装zsh,并配置些重要插件
  19. 如何在非简体中文版XP下面玩魔兽争霸
  20. arduino 温度调节器_怎样使用Arduino制作自己的温度控制器

热门文章

  1. MFC基础类及其层次结构
  2. STM32 CAN 过滤器、滤波屏蔽器配置总结
  3. STM8S105系列单片机管脚复用配置(选项字节的配置)
  4. LeetCode5377. 将二进制表示减到1的步骤数
  5. Html 教程 (7)布局
  6. C++(十)——模板(上)
  7. CTF——angr使用学习记录
  8. [密码学] 高级加密标准AES
  9. 多级cache之间的替换(缓存)策略
  10. 博客笔记导读目录-temp