Day7

  • Day7-part1
    • 平衡二叉树
      • AVL
        • LL型失衡
        • RR型失衡
        • LR型失衡
        • RL型失衡
      • Red-Black
        • 恢复平衡操作
        • 插入节点分析
          • 场景一:红黑树为空树
          • 场景二:插入节点的父节点为黑色
          • 场景三:插入节点的父节点和叔叔节点为红色
          • 场景四:插入节点的父节点为红色,叔叔节点为黑色,父亲节点为爷爷节点的左节点
          • 场景五:插入节点的父节点为红色,叔叔节点为黑色,父亲节点为爷爷节点的右节点
  • Day7-part2
      • 实现方法
      • 增添操作
      • pop最小值操作
      • 代码实现
    • 优先级队列
  • 总结

Day7-part1

Balanced Binary Trees, Red-Black Trees 平衡二叉树,红黑树

平衡二叉树

先回忆一下一个概念叫做二叉搜索树,BST。他的特点是:left < middle < right
在Day7的所有讨论中,我们的二叉树都是二叉搜索树。

当我们利用BST在进行搜索时,搜索特定值的方法是什么呢?
应该是 判断 value( < = > )cur.value,如果小于: cur=cur.left ; 如果大于: cur=cur.right;如果等于,return

通过这样的方法完成搜索,比较理想的情况,时间复杂度应该是O(logn),但是如果这颗BST结构不是特别ok呢?比如全部位于一侧的话,那么二叉树其实就类似于一个单链表,时间复杂度退化为O(n),太慢了!

为了避免这样的情况发生,我们应该采取什么措施避免呢?
我们应用了平衡二叉搜索树,balanced BST
平衡二叉搜索树的性质:

  1. 包含二叉搜索树的基本性质:left的value值 < middle的value值 < right的value值
  2. 对于balanced BST,它的任意子树也还是balanced BST
  3. 左右子节点的高度差最多为1 (下面第一个图是balanced 第二个图是unbalanced)


好的,我们现在清楚了基本概念了,做一个判断题,这个二叉树是不是balanced BST?

很明显,这不是一个balanced BST,在点22处发生了不平衡现象,下面的这颗二叉树才是balanced

深度为n的二叉树,针对平衡二叉树,最多能容纳的结点个数为N=(2^n-1),那么如果对其进行搜索时,最多需要搜索多少次呢。想一下我们的搜索策略?很明显应该为 log2(N),在这里也就是n次!

当我们的数据量加倍,现在有2N个结点的二叉树需要我们搜索呢?次数应该为log2(N)+1次, 可以看出搜索的代价减少了很多!

现在的一切事情是不是看起来很美好啦?但是完全美好的事物中一定有挥之不去的阴影存在!
当我们对balanced BST进行 插入和删除 的时候,很有可能就导致平衡的结构发生了改变,就从balanced 变成 unbalanced了。

我们需要一种方法把unbalanced变成balanced,这样才能不断延续我们美好的搜索策略?常见的方法包含AVL方法和 Red-Black Tree 方法。我这里也给你说一下AVL方法吧,虽然PPT里面只说了红黑树。我个人认为AVL是红黑树的基础,

AVL

AVL树是一种带有自平衡功能的二叉查找树

针对上面这个图,在插入key为1的节点后,变成了unbalanced。AVL通过旋转的方式完成了平衡调整。分别包括左旋和右旋。
失衡的四种场景
主要包括LL型失衡RR型失衡LR型失衡RL型失衡

LL型失衡

LL型失衡:新插入结点在root的左侧,其父亲的左侧
解决这种失衡:以root的left为支点进行旋转,并且按照BST排列


RR型失衡

RR型失衡:新插入结点在root的右侧,其父亲的右侧
解决这种失衡:以root的right为支点进行旋转,并且按照BST排列

LR型失衡

LR型失衡:新插入结点在root的左侧,其父亲的右侧
解决这种失衡:先以其父亲为支点作一次左旋,随后进行一次右旋。

RL型失衡

RL型失衡:新插入结点在root的右侧,其父亲的左侧
解决这种失衡:先以其父亲为支点作一次右旋,随后进行一次左旋。


二叉树的失衡无外乎以上四种情况,针对由插入和删除导致的任何不平衡问题。
可以对其进行判别,重复进行旋转,获得一棵平衡的二叉树。
但是不可避免,要花很长的时间应用于二叉树调整。
搜索时间复杂度O(logn)

Red-Black

红黑树的特点

  1. 每个节点是红色/黑色的
  2. 根节点是黑色的,叶子结点也是黑色的
  3. 红色节点的父节点是黑色的
  4. 从任一节点到叶子节点的所有路径,经过的黑色节点数量相同(black height)
    红黑树可以没有红色点
    在进行插入操作的时候,将新插入的节点设置为红色。设置为红色的原因:设置为黑色很可能会导致(4)的破坏,导致黑色节点数量不同。


你看一下上面这个图的第二个图,很容易就看的出来:这并不是一棵balanced BST。那是不是和我们的原则相违背了呢?
其实不是这样的,红黑树的平衡条件,是以黑色高度来进行约束的。只需要满足黑色高度相等,就认为达到了黑色完美平衡。

恢复平衡操作

当进行插入/删除操作的时候,很有可能导致红黑树的平衡被破坏。
回复平衡的操作包括:
1.变色:节点由红色变为黑色,或者黑色变为红色
2.右旋

3.左旋

插入节点分析

场景一:红黑树为空树

将插入节点作为红黑树的根节点,同时将其设置为黑色。

场景二:插入节点的父节点为黑色

新插入的节点为红色,父节点为黑色,因此可以直接插入,无需自平衡。

场景三:插入节点的父节点和叔叔节点为红色

将父亲(F)和叔叔(V)节点变为黑色
将爷爷§节点设置为红色(为了确保左右黑色高度相等)
如果爷爷节点(P)为根节点,再把根节点设置为黑色。
如果P不为根节点,且P的父节点为红色,继续进行自平衡处理。直到整体平衡

场景四:插入节点的父节点为红色,叔叔节点为黑色,父亲节点为爷爷节点的左节点

1. LL失衡

  1. P设置为红色,F设置为黑色
  2. 对F进行右旋

2. LR失衡

  1. 进行一次左旋,针对K
  2. 随后重复LL失衡操作
场景五:插入节点的父节点为红色,叔叔节点为黑色,父亲节点为爷爷节点的右节点

1. RR失衡

  1. P设置为红色,F设置为黑色
  2. 对F进行左旋

    2. RL失衡
  3. 对F进行右旋
  4. 按照RR失衡处理

以上就是所有的插入操作了!

思考以下几个问题:
1.红黑树特点
2.红黑树相比较AVL的优势:允许内部不平衡,减少了部分的旋转操作
3.红黑树恢复平衡操作
4.红黑树如何实现插入操作

Day7-part2

Heaps, Priority Queues 堆,优先级队列

堆是一种类似于完全二叉树的数据结构,长得和完全二叉树一个样子。
最小堆:根节点值最小,父亲节点值小于子节点值
最大堆:根节点值最大,父亲节点值大于子节点值

在这种存储方式下,针对节点 i
左节点 2i 右节点 2i+1 父亲节点 i//2

实现方法

  1. 很直观来看,我们可以用二叉树来实现堆
    但是存在一些问题,第一个是针对二叉树,其构造依赖于技巧,同时在增添节点时不容易增加。
  2. 还可以通过列表来实现堆,美中不足的是,不要忘记列表从0开始索引。

    接下来,我们的讨论均针对最小堆

增添操作


在最小堆中我们增加一个元素6

很显然,目前的状态是不满足最小堆的性质的。
我们需要将6进行合理的排列,怎么做呢?
最小堆的性质:父亲节点的值应小于当前结点的值 我们是不是逐步向前比较就好了?
6和40比较,6<40,随后交换位置
6和11比较,6<11,随后交换位置
6和8比较,6<8,随后交换位置
最终完成排列

pop最小值操作

我们想把堆中的最小值取出来,并且堆仍然满足最小堆的条件!

首先最小值很好取,肯定就是nums[ 0 ],我们把这个值保存下来,最后return出来就好了
关键是如何满足最小堆的条件?
将nums[ 0 ] 和最后一个节点(40)交换位置,再将最后一个节点删除。
随后按照性质,把root节点放在合适的位置
40和7比较,7<40,随后交换位置
40和22比较,22<40,随后交换位置

代码实现

class heap:def __init__(self,nums=[]):self.nums=[]if nums:self.buildheap(nums)def isempty(self):return not self.numsdef buildheap(self,nums):for x in nums:self.insert(x)def insert(self,a):self.nums.append(a)cur=len(self.nums)-1while(cur>0):if a<self.nums[(cur-1)//2]:self.nums[cur],self.nums[(cur-1)//2]=self.nums[(cur-1)//2],self.nums[cur]cur=(cur-1)//2else:breakdef sift_down(self,cur):while(cur<=len(self.nums)//2):left=2*cur+1right=2*cur+2if left >len(self.nums)-1:breakelif left<len(self.nums) and right<len(self.nums):if self.nums[cur]>self.nums[left]:self.nums[cur],self.nums[left]=self.nums[left],self.nums[cur]cur=leftcontinueelif self.nums[cur]>self.nums[right]:self.nums[cur],self.nums[right]=self.nums[right],self.nums[cur]cur=rightcontinueelse:breakelse:if self.nums[cur]>self.nums[left]:self.nums[cur],self.nums[left]=self.nums[left],self.nums[cur]cur=leftelse: breakdef remove(self):result=self.nums[0]self.nums[0],self.nums[len(self.nums)-1]=self.nums[len(self.nums)-1],self.nums[0]self.nums.pop()self.sift_down(0)return resulth=heap([1,2,3,7,8,5,3])
h.remove()
print(h.nums)

优先级队列

数据带有优先级,一般出队列时,可能需要优先级高的元素先出队列。
通过堆实现
具体的PPT也没说掌握到什么,我也就先不看了哦!

总结

这一部分什么最重要?
概念的理解最重要
红黑树的性质?红黑树如何恢复平衡?红黑树插入操作?
堆的性质?如何实现?
加油宝贝,我相信你可以的!

  • 尚想旧情怜婢仆,也曾因梦送钱财。 诚知此恨人人有,贫贱夫妻百事哀。

参考:https://blog.csdn.net/crazymakercircle/article/details/125017316

Python prep 随想练习 Day7-红黑树相关推荐

  1. Python实现红黑树

    红黑树是一颗二叉搜索树,他在每个节点上增加了一个存储位来表示节点的颜色,可以是RED或者是BLACK,树中的每个节点包括5个属性:color.key.left.right.parent,如果一个节点没 ...

  2. 数据结构之平衡树:红黑树的介绍与Python代码实现——17

    红黑树的介绍与Python代码实现 红黑树的介绍 红黑树(Red-Black Tree)是一种平衡二叉查找树,它是一种以比较简单的方式实现的2-3查找树 红黑树基于2-3查找树的表现 红链接:将两个2 ...

  3. Python实现红黑树的删除操作

    Python实现红黑树的删除操作 本专栏的上一篇文章使用Python实现了红黑树的插入操作.参考:https://blog.csdn.net/weixin_43790276/article/detai ...

  4. Python实现红黑树的插入操作

    Python实现红黑树的插入操作 本专栏中的上一篇文章介绍了什么是红黑树,以及红黑树的旋转和变色. 参考:https://blog.csdn.net/weixin_43790276/article/d ...

  5. python:实现红黑树算法(附完整源码)

    python:实现红黑树算法 from __future__ import annotations from collections.abc import Iterator class RedBlac ...

  6. python 红黑树_python学习笔记|红黑树(性质与插入)

    定义 一种含有红黑节点并能自平衡的二叉查找树(BST) 性质 1.每个节点有红/黑标记位 2.根节点是黑色(硬性规定) 3.每个叶子节点(NIL)都是黑色的虚节点(由此引出性质5) 叶子节点 colo ...

  7. python【数据结构与算法】红黑树概念辨析

    文章目录 1 二叉查找树 2 AVL 3 红黑树 1 二叉查找树 二叉查找树,Binary Search Tree 「BST」,要想了解二叉查找树,我们首先看下二叉查找树有哪些特性呢? 某节点的左子树 ...

  8. 算法导论 第十三章 红黑树(python)-1插入

    红黑树是上一章二叉搜索树的改进,实现一种平衡 ,保证不会出现二叉树变链表的情况,基本动态集合操作的时间复杂度为O(lgn) 实际用途:c++stl中的set,map是用他实现的 红黑树的性质: 1.每 ...

  9. 4岁的儿子还不会写红黑树,我该怎么办?

    程序员书库(ID:OpenSourceTop) 编译 书单来自:https://www.codemom.ai/best-coding-books-for-kids/ 身为一名程序员,很多人肯定会认为程 ...

最新文章

  1. 扩增子统计绘图1箱线图:Alpha多样性
  2. Iptables防火墙详细介绍与实战增强服务器安全
  3. python读excel字体颜色_无法使用python xlsxwri更改excel中的字体颜色
  4. html 显示搜索结果,搜索结果高亮显示(不改变html标签)
  5. 进程间通信IPC(二)(共享内存、信号、信号量)
  6. php session 保存数组,php - 我用ajax设置的SESSION数组变量没有被保存?
  7. 都说变量有七八种,到底谁是 Java 的亲儿子
  8. 【PL/SQL】 使用游标
  9. macOS 下的数据库客户端工具
  10. win10如何调整计算机时间同步,win10电脑时间与Internet同步的设置方法
  11. 2021国赛参赛经验与感悟
  12. 需求分析师如何提高核心竞争力
  13. win10 EFI文件夹删除了,引导进不去了,该怎么办?
  14. java搭建直播商城VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城
  15. object标签属性详解
  16. SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified
  17. java jfinal_如何使用JFinal开发javaweb
  18. 车好多 CTO,关于中台的思考和尝试
  19. java-net-php-python-java在线花店网站计算机毕业设计程序
  20. 盘点微信中被隐藏的实用功能

热门文章

  1. clover安装Mac big sur卡在Attempting system restart...MACH Reboot
  2. ChatGPT教你怎么样论文写的又快又好
  3. 什么是网关,网关的作用是什么?
  4. 前端开发之vue可视化数据图表组件(Chart.js)
  5. c语言remove命令和erase,详解C++ list中erase与remove函数的使用
  6. React.forwardRef
  7. java pojo 转 map_如何将POJO对象转换成MAP
  8. python实现三层神经网络 (BP)
  9. 大咖说|《商业评论》主编颜杰华:如何看待未来商业的管理趋势?
  10. “拙荆记春梦”孙溟㠭篆刻作品“有所不为”