二分搜索树和AVL树

news/2024/7/7 20:00:32

问题

跑道预订系统。一个飞机场只有一个飞机跑道,需要为未来的飞机着陆预留空闲的跑道。飞机预订的着陆时间为t,假如没有其他的计划在(t-k,t+k)的时间内着陆的飞机,则将t加入集合R。其中k是变量。请问有没有一种时间复杂度为O(logn)的算法解决这个问题?

例子

3ac294a0961d4b51a820727b74370d17.jpeg

如果现在时间是37, 在R集合中,在41.2,49,和56.3三个时间点上,其他飞机已经预订了跑道。如果有架飞机要预订t=53进行着陆,是可以的,因为49+3<53<56.3-3;而如果是t=44,飞机无法安排因为t=41.2的飞机着陆完毕后t=41.2+3=44.2>41.2。而t=20的时间也不能安排,因为现在已经是t=37了。

如果集合R是未排序的数组或链表;则插入需花费O(1)的时间,但插入前需要依次和集合中的所有元素进行比较,花费的时间是O(n)。

如果时间集合R是个已排序的数组或链表,我们可以尝试用二分查找来做,查找的时间复杂度为O(logn),但如果是数组,则插入时需要移动大量元素,时间复杂度为O(n),总时间复杂度为O(logn+n)。如果是单纯的链表,则无法使用二分查找法。 

以上几种方式都无法满足O(logn)的需求。

二叉搜索树

binary search tree(BST)

8cbd4696bab34e14a53006b4b8043119.jpeg

二分搜索树的不变式对于所有结点x:

  • 如果y是x的左子树,y的值 ≤ x的值;
  • 如果y是x的右子树,y的值 ≥ x的值;

例子在图中。

若h为BST的高度,那么插入元素(不带检查)的时间复杂度是Ο(h)。

最好的情况是BST为平衡的,h=logn,时间复杂度为O(logn)。最差的情况是BST变成一条链表,h=n,时间复杂度为O(n)。

显然BST还是无法完全满足要求。为什么呢?因为BST不平衡。

为此提出了平衡二叉树AVL。

AVL 

我们称BST是平衡的,如果其高度为logn。

AVL树的性质:每一个结点的左右孩子结点的高度差距最多为±1。即 eq?%7Ch_%7Bl%7D-h_%7Br%7D%7C%5Cleq%201

AVL树是平衡的。

结点的高度

结点的高度等于该结点到以其作为根节点的子树的叶子结点的最长路径。

等于max{height(left child),height(right child)}+1

AVL树的最少结点数与最大高度

AVL树是平衡的。最差的情况是每一个结点的左右孩子结点的高度差为1.

记Nh=高度为h的AVL树的最少结点数量,并且根据AVL的递归性质可得:

eq?N_%7Bh%7D%20%3D%201%20&plus;%20N_%7Bh-1%7D%20&plus;%20N_%7Bh-2%7D

由Nh的递归式我们可以估算AVL树的最大高度。

这个数列与斐波那契数列相似。会得到Nh > Fh = (φ^h)/√5,其中Fh是斐波那契数列(数字1,1,2,3,5,8-构成了一个序列。这个数列前面相邻两项之和,构成了后一项),φ=1.618,最后可以通过下图的得到h小于1.44log2n

一个更粗略的估算是eq?N_%7Bh%7D%20%3E%201&plus;2*N_%7Bh-2%7D%20%3E%202*N_%7Bh-2%7D%20%3D%20%5CTheta%20%282%5E%7B%5Cfrac%7Bh%7D%7B2%7D%7D%29,因此h < 2*logn

AVL树的插入

分为两步

①根据BST的规则进行插入

②对插入后的BST进行重新平衡,使其符合AVL树的性质。

左旋与右旋

f3d01935ec224cf79c120840d21adaec.jpeg

进行左旋或右旋操作后,从左往右的次序保持不变。

例子

3c3de569bff54670b58d42383db3dddc.jpeg

往已有的AVL树中插入23,不符合AVL性质,右旋29,符合AVL性质。

80960e128f134f1e9d7255d6b37263c6.jpeg

插入55,不符合AVL性质,左旋50,还是不符合AVL性质,再右旋65,最终符合AVL。进行了两次旋转。

平衡因子

在二叉树中,节点 X 的平衡因子被定义为高度差

重新平衡

详细讨论AVL插入的步骤②

  • 假设x是最低的违背AVL性质的结点(其平衡因子为+2或-2)
  • 假定z是拥有更高子树的孩子

有两种情况

①单次旋转

d384be5fd01e4d7da5922945a15fb1e9.png

②两次旋转

3fb5ae8ab95a44469c6a574b49bb94cd.png

AVL排序

1.按AVL的规则,插入n个结点。O(nlogn)

2.中序遍历AVL树。O(n)

故AVL排序的时间复杂度为O(nlogn)

ADT

一个抽象数据类型规定了 插入/删除、返回最小值、返回前驱/后继 三种操作。

使用Heap可以实现插入/删除和返回最小值。但是如果还要求next_larger和next_smaller(前驱和后继),则需要平衡的BST。

488cefa1c35944fd98bb95558f4c3e1e.jpeg

 


http://lihuaxi.xjx100.cn/news/2090675.html

相关文章

九州金榜|小学生产生厌学应该怎么办?

随着寒假结束&#xff0c;孩子们也步入的正常校园生活&#xff0c;现在孩子们开学已经三周了&#xff0c;可是孩子很多孩子进入不了学习状态&#xff0c;尤其是小学生&#xff0c;还沉寂在假期中&#xff0c;孩子不想学习&#xff0c;其实这是孩子厌学的一中表现&#xff0c;很…

淘宝商品详情数据采集(商品属性,规格,价格,详情图等)

淘宝商品详情数据采集是一个涉及多个步骤的过程&#xff0c;主要目的是获取商品的各种详细信息&#xff0c;如商品属性、规格、价格、详情图等。以下是一个基本的采集流程&#xff1a; 确定采集目标&#xff1a;首先&#xff0c;需要明确要采集的淘宝商品范围&#xff0c;例如…

揭秘FastStone Capture:一款强大且高效的截图工具

目录 【引子】【FastStone Capture概述】【安装步骤】【使用攻略】【核心功能解析】【总结】 【引子】 在数字化信息时代&#xff0c;无论是工作汇报、在线教学&#xff0c;还是日常交流中&#xff0c;屏幕截图已经成为我们必不可少的辅助工具。今天&#xff0c;我要为大家详细…

中国电子学会2022年9月份青少年软件编程Sc ratch图形化等级考试试卷四级真题

1.运行下列程序&#xff0c;说法正确的是&#xff1f; A&#xff1a;列表中的数字全部小于11 B&#xff1a;列表的长度为10 C&#xff1a;变量i最终值为20 D&#xff1a;列表中有大于10的数字 2.按钮Button3的当前造型为第2个造型&#xff0c;运行下列程序&#xff0c;正确…

Vue 中如何进行非父子组件通信?

说在前面 &#x1f388;在构建复杂的 Vue 应用程序时&#xff0c;我们经常会遇到需要在非直接父子关系的组件之间进行通信的情况。本文将深入探讨 Vue 提供的多种非父子组件通信方法&#xff0c;并提供实用的代码示例和应用场景。 常见通信方法 在 Vue.js 中&#xff0c;非父子…

C#多线程(5)——异步方法async与await

在上一章节中&#xff0c;为大家介绍了C#多线程&#xff08;4&#xff09;——任务并行库TPL&#xff0c;TPL是从.NetFramwork4.0后引入的基于异步操作的一组API&#xff0c;核心关注于任务【 T a s k 和 T a s k < T > \textcolor{red}{Task 和 Task<T>} Task和Ta…

AI 技术:改变世界的力量

人工智能&#xff08;AI&#xff09;是当今科技领域最热门的话题之一&#xff0c;它已经成为推动社会进步和经济发展的重要力量。AI 技术的应用范围非常广泛&#xff0c;从智能手机、自动驾驶汽车到医疗保健、金融服务等领域&#xff0c;都可以看到 AI 的身影。 那么&#xff0…

Centos 安装 redis【最简单】

Centos7 使⽤ yum 安装 ⾸先安装 scl 源, 再安装 redis &#xff08;因为 Centos7 yum 提供的软件包只有 3.0 版本的 Redis &#xff0c;太老了&#xff0c;我们要安装 redis 5 系列的&#xff09; yum install centos-release-scl-rh yum install rh-redis5-redis 创建符号…