算法设计与分析6
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【例3】查找问题 —— 在 n 元列表中查找给定键
蛮力法:顺序查找,最差情况需 n 次比较,O(n) 变治法:预排序 + 折半查找,时间效率:
T ( n) Tsort ( n) Tscan ( n) O( n log n) O(log n) O( n log n)
可见预排序比顺序查找的时间效率更差。对于在同一个列表中查找 次数很少的问题,不如顺序查找。若对同一个列表需要很多次查找, 效率将超过顺序查找。(分摊效率) 预排序的其他应用
★ 堆 (Heap) 与优先队列 (Priority queue)
堆是一种数据结构,尤其适合用来实现 优先队列 。 优先队列 —— 按对象的 优先级 属性排序的对象集合。
第 6 章 变治法
★ 变治策略
★ 预排序 ★ 平衡查找树
AVL树
2-3树(扩展B、B+、B* 树)
★ 堆与优先队列
★ 堆排序(堆分类)
★ 问题化简 ★ 本章习题
第 6 章 变治法
★ 变治策略
★ 预排序 ★ 平衡查找树
AVL树
2-3树(扩展B、B+、B* 树)
★ 堆与优先队列
★ 堆排序(堆分类)
AVL树是BST,用BST插入算法生成。 插入新节点后,若 AVL 树失去平衡,进行旋转,重新平衡它。 节点有 4 种插入位置,对应 4 种旋转变换: 1. 最近不平衡节点的左子树的左节点 —— 右单转,R旋转 2. 最近不平衡节点的右子树的右节点 —— 左单转,L旋转 3. 最近不平衡节点的左子树的右节点 —— 左右双转,LR旋转
n ≥ 2h+1 – 1 即 h ≤ log2(n+1) – 1
2-3 树全部由 3 节点构成:当前层节点数 = 3×上一层节点数 n = 30 + 31 + 32 + ... + 3h = 3h+1 – 1
一般的 2-3 树(既有 2 节点又有 3 节点),节点总数:
n ≤ 3h+1 – 1 即 h ≥ log3(n+1) – 1 综合1、2:log3(n+1) – 1 ≤ h ≤ log2(n+1) – 1 无论最差或平均情况,2-3 树字典操作(插入、删除、查找)的时间 效率都属于Θ(logn) 型。2-3 树有重要的扩展形式 B、B+、B* 树
K
K1 , K2
<K
≥K
< K1
[K1, K2)
≥K2
2-3 树的两种节点类型
举例说明:2-3 树生成(插入)算法的过程图示 将序列 { 9, 5, 8, 3, 2, 4, 7 } 构造一棵 2-3 树 分裂,提升
8
5 9 3,5
8 9
9
5,9
5,8,9
8 2,3,5 9
3,8 2 5 9 2
3
T
2
1
T1
T4
T1
AVL树效率:它是BST,效率与BST一样取决于树高:
log2 n h 1.4405log2 (n 2) 1.3277
AVL树缺点:频繁的旋转、维护树节点平衡,设计上较复杂,尤其是 删除操作,妨碍了其应用。但蕴涵的思想使人们发现了 BST 的其他变种。
树高:根到叶的最长路径的边数。设根为 0 层,树高 = 最底层编号
节点平衡因子:左子树高 - 右子树高 AVL 树:每个节点的平衡因子均为 0、-1、+1
1
2 1
20
0
5
10
0
5
10
0
20
1
4
1
7
0
12
1
4
1
7
0
2
0
8 AVL树
0
2
0
8 非AVL树,BST
AVL树生成(插入)算法
while ( i≤n-1 )
runlength←1,runvalue←A[i] // 行程长度 = 等值元素个数 while ( i+runlength≤n-1 and A[i+runlength] = runvalue )
runlength ++ // 与下一个元素相等则行程长度+1
if ( runlength > ModeFrequency ) ModeFrequency←runlength,modeValue←runvalue i←i+runlength // 跳过本行程,i 始终指向行程的第一个元素 return ( ModeValue, ModeFrequency )
3,8 4,5 8 9 4,8 5 9 9
2-3 树时间效率
时间效率取决于 树高(h),下面考察 2-3 树的两种极端的树高 树高:从根到叶最长路径的边数 = 最大层号(根为 0 层) 2-3 树全部由 2 节点构成:当前层节点数 = 2×上一层节点数 一棵满的完全二叉树( n 个节点,高度 h),节点总数: n = 20 + 21 + 22 + ... + 2h = 2h+1 – 1 一般的 2-3 树(既有 2 节点又有 3 节点),节点总数:
需要与辅助列表中已加入的 k-1个元素比较,共 k-1 次。
最差效率:
T ( n) ( k 1) 1 ... n 1 (n2 )
k 1
n
变治法 —— 预排序(nlogn型),排序后 等值元素一定相邻 扫描统计:模式具有最多的相邻元素,需比较 n -1 次。 PresortMode_1(A[0...n-1]) // 行程算法 对数组A排序 // 排序结果 { 1, 5, 5, 5, 6, 7, 7 } i←0,ModeFrequency←0 // 最大频率,最大行程长度
【例1】检验数组中元素的唯一性
蛮力:逐个比较数组元素,直到找到两个相等元素或全部元素比较 完毕为止。时间效率 O (n2) 变治:预排序化简问题后求解。即:数组排序后检查连续元素。 排序后等值元素(重复元素)一定相邻 算法 PresortElementUniqueness ( A[0...n-1] ) 对数组A排序 // 选nlogn型算法
0
2
右子树的左节点
2
w
R(w)
T
3
0
e
1
e
0
w
T
1
T
1
T
2
1
1
T
2
T
3
右单转的一般情况(左子树左节点)
2 1
e k
T4 T1
2
L(e)
w
2
w
1
0
e
k
T
3
T4
T
2
T
3
1
T1
T
2
1
or
左右双转的一般情况(左子树右节点) (先左单转,后右单转)
2 2
w k
R(w)
0 0
e
k
1
w
0
e
T
3
T4
T
2
T
3 种主要类型
实例化简:问题求解变得更简单,如预排序
改变表现:改变问题的表现形式,如AVL树,2-3树,堆
问题化简:问题变为另一个问题。如数学建模,将具体应用问题用 变量、函数、方程等数学对象表达
更简单方便 问题
另一种表现
另一个问题
求解
★ 预排序
古老思想:若列表有序,一些与列表有关的问题更容易求解。 —— 依赖于排序算法的时间效率
2. 确定查找分支,转 1
2-3 树删除算法 —— 删除键而非删除节点 —— 删除一个键时,2 节点情况与 BST 相同。 —— 对于 3 节点情况,分 3 种情况: 1. 叶节点,有 2 个键:删除右图 “ 4 ” 键 —— 简单删除 “4”,2-3 树性质不变 2 2. 叶节点,仅 1 个键:删除右图 “ 2 ” 键 简单删除2,不符合 2-3 树性质。 若相邻兄弟无多余键(仅1个,如去掉 “4” ), 3,5 将该相邻兄弟和父节点中、它俩的分界键 并入已删除键的空节点中。 若相邻兄弟有多余键(如 “4”、“5”) 借码 —— 把该兄弟的 2 个键和父节点中的 3 分界键并入该空节点,再作分裂 3. 内部节点(非叶节点):如删除右上图 “3” 键 删除仅在叶节点进行,替换后再删除替换键(图略) 替换键 —— 比该键大的子树中的最小键
3,8 4,5
5
9
3,8 2 4,5,7 9 2
3,5,8 4 7 9
3
8
2
4
7
9
2-3 树插入算法(3 阶B 树)
—— 注意保持 2-3 树的性质 1. 用查找算法找到恰当的叶节点位置,插入新节点
2. 若插入节点溢出,分裂该节点,中间键(键值大小)加入父结点
—— 若父结点溢出,继续分裂父节点 —— 若分裂过程向上传递到根节点,树加高一层 2-3 树查找算法(类似 BST ) 从 2-3 树的根节点开始: 1. 查找当前节点 —— 若找到关键码(键),查找成功返回 —— 若未找到,且当前节点已是叶节点,查找失败返回
for i←0 to n-2 do if A[i] = A[i+1] return false return true
T ( n) Tsort ( n) Tscan ( n) O( n log n) O( n) O( n log n)
【例2】模式统计
模式:列表中出现频率最高的元素。 如 { 5, 1, 5, 7, 6, 5, 7 } 的模式为 5,模式可能不止一个 问题:在列表中找出模式 蛮力策略:扫描列表,统计每个元素的频率,找出频率最高的元素 蛮力实现:(方法之一) 设一个辅助列表,扫描元素与辅助列表中的元素一一比较,结果: 若匹配(辅助列表中已有),该元素频率加1. 不匹配(辅助列表中没有),新元素加入辅助列表,其频率置1. 本例最终的辅助列表:{ 5(3), 1(1), 7(2), 6(1) } 括号内为频率。 —— 扫描辅助列表,找出最大频率(3)的元素(5) 最坏情况:扫描原始列表时,每个元素在辅助列表中都没有匹配, 作为新元素加入辅助列表,原列表的第 k 个元素加入辅助列表时,
2-3 树 —— BST的变体
2-3 树的特性(定义) 1. 每个节点包含 1 个或 2 个键
2. 每个内部节点有 2 种类型:
2 节点 —— 1 个键 K,2 个子女 3 节点 —— 2 个键 K1< K2,3 个子女(键值关系如下图) 3. 所有叶节点在树的同一层,树高平衡 K1< K2 2节点 3节点
非行程算法(比较次数 n-1)
PresortMode_2(A[0...n-1]) 数组A排序 // 结果 { 1, 5, 5, 5, 6, 7, 7 }
ModeFrequency←1 // 模式频率
ModeValue←A[0] for ( i←0 to n-2 ) // 模式值 【思考】
Current_F←1 // 当前频率
4. 最近不平衡节点的右子树的左节点 —— 右左双转,RL旋转
2
3
0
R(3)
2
1
2
0
1
0
3
0
1
左子树的左节点
2
1
1
2
L(1)
0Hale Waihona Puke Baidu
2
0
3
0
1
0
3
右子树的右节点
2
3 L(1) 3 2 R(3) 2
0 0
1
1
1
0
3
0
2 1
左子树的右节点
2
1 R(3) 1
2
L(1)
0
2
1
3
1
2
0 0
3 1
0
3
—— 许多处理点集的计算几何算法
例如:点集的排序 可根据它们的坐标,或者到某特定直线的距离,或者某种角度等等。
如在最近对、凸包问题的分治算法中,都曾采用了预排序技术。
★ 平衡查找树
二叉查找树 BST 是一种重要的数据结构,是集合的一种描述方式。 集合用 BST 描述是改变表现形式的一种变治技术。 BST 与线性表相比,查找、插入和删除操作的时间效率较好,属于 logn 型(平均),最坏 O(n) —— 退化为一棵完全不平衡树(链) 保持 BST 的好特性,避免退化的两种方案 —— 【实例化简】 对不平衡 BST 进行各种变换,重新构造平衡树。不同算法对BST的 平衡要求不同。如AVL树平衡:每个节点左右子树高度差≤1 .
【改变表现】
BST 每个节点仅允许有 1 个键(查找的属性)。 允许每个节点可包含不止一个键。典型例子:
2-3 树、2-3-4 树,更一般的 B 树(B+ 树、B* 树)
AVL 树 (1962,前苏联科学家G.M.Adelson-Velsky, E.M.Landis)
AVL 树是 BST.
★ 问题化简 ★ 本章习题
第 6 章 变治法
★ 变治策略
★ 预排序 ★ 平衡查找树
AVL树
2-3树(扩展B、B+、B* 树)
★ 堆与优先队列
★ 堆排序(堆分类)
★ 问题化简 ★ 本章习题
★ 变治策略
通用的算法设计方法,基于变换的思想
变:变换问题更容易求解 治:对变换后的问题求解
if A[ i ] = A[ i+1] Current_F ++
1. A 元素全部唯一
2. A 元素全部相等
if Current_F > ModeFrequency
ModeFrequency ← Current_F ModeValue ← A[ i ]
return (ModeValue, ModeFrequency)