减治法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2 3 4 1 · · ·· · 1 2 4 3 · · ·· · · ·4 3 · · · · ·
· · 3 4
· · · · ·
选择问题的查找过程示例(查找第4小元素)
ຫໍສະໝຸດ Baidu
算法5.7——选择问题 1. i=1; j=n; //设置初始查找区间 2.以r[i]为轴值对序列r[i]~r[j]进行一次 划分,得到轴值的位置s; 3. 将轴值位置s与k比较 3.1 如果k=s,则将r[s]作为结果返回; 3.2 否则,如果k<s,则j=s-1,转步骤2; 3.3 否则,i=s+1,转步骤2;
a n a
n
a
2
n 1
2
a n
n 1
分治法和减治法区别
分治法是对分解的子问题分别求解,需要对子问 题的解进行合并,而减治法只对一个子问题求解, 并且不需要进行解的合并。应用减治法(例如减 半法)得到的算法通常具有如下递推式:
0 T (n) T ( n / 2) 1
(3)若k>s,则第k小元素一定在序列rs+1 ~ rj中且为第 k-s小元素; 无论哪种情况,或者已经得出结果,或者将选择问题 的查找区间减少一半(如果轴值恰好是序列的中值)。 选择问题的减治思想如图5.10所示。
[ ri … rk … rs-1 ] rs [ rs+1 … … rj ] [ ri … … rs-1 ] rs [ rs+1 …rk … rj ]
52
low=1
设置初始区间 mid=7
high=13 查找区间为[1, 13] 取中点mid=7 比较r[7]与k,将查找调整到左半区
low=1 mid=3 low=1 high=2 mid=1 low=high=2 mid=2
high=6
查找区间为[1, 6] 取中点mid=3 比较 r[3]与k,将查找调整到左半区 查找区间为[1, 2] 取中点mid=1 比较r[1]与k,将查找调整到右半区 查找区间为[2, 2] 取中点mid=2 比较r[2]与k,查找成功,返回mid的位置2
n 1 n 1
查找问题中的减治法
折半查找
二叉查找树
折半查找
在有序表{ 7, 14, 18, 21, 23, 29, 31, 35, 38, 42, 46, 49, 52 }中查找值为14的 记录的过程如图所示。
0 1
7
2
14
3
18
4
21
5
23
6
29
7
31
8
35
9
38
10
42
11
46
12
49
13
图 折半查找成功情况下的查找过程
折半查找 1. low=1;high=n; //设置初始查找区间 2. 测试查找区间[low,high]是否存在,若不存 在,则查找失败;否则 3. 取中间点mid=(low+high)/2; 比较k与r[mid],有 以下三种情况: 3.1 若k<r[mid],则high=mid-1;查找在左半区 进行,转2; 3.2 若k>r[mid],则low=mid+1;查找在右半区 进行,转2; 3.3 若k=r[mid],则查找成功,返回记录在表中位 置mid;
原问题 的规模是n
子问题 的规模是n/2 子问题的解
原问题的解
图5.1 减治法的典型情况(减半技术)
对于给定的整数a和非负整数n,计算an的值。
利用减治法,如果n=1,可以简单地返回a的值,如果n是偶数并且n>1,可 以把该问题的规模减半,即计算an/2的值,而且规模为n的解an和规模减半 的解an/2之间具有明显的对应关系:an=(an/2)2,如果n是奇数并且n>1,可 以先用偶指数的规则计算a(n-1),再把结果乘以a。所以,应用减治技术得到 如下计算方法:
考虑快速排序中的划分过程,一般情况下,设待划分的 序列为ri ~ rj,选定一个轴值将序列ri ~ rj进行划分, 使得比轴值小的元素都位于轴值的左侧,比轴值大的元 素都位于轴值的右侧,假定轴值的最终位置是s,则: (1)若k=s,则rs就是第k小元素; (2)若k<s,则第k小元素一定在序列ri ~ rs-1中且为第 k小元素;
T ( n) T ( n 1) O ( n)
使用扩展递归技术对递推式进行推导,得到该递推式的解是 O(n2),这是最坏情况;平均情况下,假设每次划分的轴值是 划分序列中的一个随机位置的元素,则处理区间按照一种随 机的方式减少,可以证明,算法5.7可以在O(n)的平均时间内 找出n个元素中的第k小元素。
simpler instance
or
problem’s instance
Another representation or another problem’s instance
solution
减治法的设计思想
(1)原问题的解只 存在于其中一个较小 规模的子问题中; (2)原问题的解与 其中一个较小规模的 解之间存在某种对应 关系。
5.4.2 假币问题
在n枚外观相同的硬币中,有一枚是假币, 并且已知假币较轻。已经有一架没有刻度的 天平,试设计一个算法使其时间复杂度为
T(n)=O(log2n)。 T(n)=O(log2n)
不知假币是轻是重?
a+b+c?d+e+f > a+e?d+b > a?h > = c?h > = < b?h g?a > g:H = h:L g?h > < h?a > = > e:H > e?h = b:L > f:H = <
算法5.7的效率取决于轴值的选取。如果每次划分的轴值恰好 是序列的中值,则可以保证处理的区间比上一次减半,由于 在一次划分后,只需处理一个子序列,所以,比较次数的递 推式应该是: T ( n ) T ( n 2) O ( n ) 使用扩展递归技术对递推式进行推导,得到该递推式的解 是O(n),这是最好情况;如果每次划分的轴值恰好是序列 中的最大值或最小值(例如,在找最小元素时总是在最大 元素处划分),则处理区间只能比上一次减少1个,所以, 比较次数的递推式应该是:
二叉查找树
在二叉查找树中查找关键字值为35,95的过程:
50 30 20 40 80 90 85 20 35 30 40 50 80 90
35
32
85
88
88
32
二叉排序树的查找 BiNode * SearchBST(BiNode *root, int k) { if (root= =NULL) return NULL; else if (root->data==k) return root; else if (k<root->data) return SearchBST(root->lchild, k); else return SearchBST(root->rchild, k); }
组合问题中的减治法
5.4.1 淘汰赛冠军问题 5.4.2 假币问题
5.4.1 淘汰赛冠军问题 问题描述:假设有n=2k个选手进行竞技 淘汰赛,最后决出冠军的选手。
算法5.8——淘汰赛冠军问题 string Game(string r[ ], int n) { i=n; while (i>1) { i=i/2; for (j=0; j<i; j++) if (Comp(r[j+i], r[j])) r[j]=r[j+i]; } return r[0]; }
a+e?d+b
= f?h = > < d?h = a:L
=
>
=
a:H d:L
c:H f:L
b:H e:L
h:H g:L
c:L d:H
图 八枚硬币问题的判定树
因为n=2k,所以,外层的while循环共执行k次,在每一次执 行时,内层的for循环的执行次数分别是n/2,n/4,…,1, 而函数comp可以在常数时间内完成,因此,算法5.8的执行 k 时间为: n 1 T ( n ) i n (1 k ) n 1 O ( n ) 2 i 1 2
均≤rs 轴值 均≥rs 均≤rs 轴值 均≥rs
(a) 若k<s,则rk在左半区
(b) 若k>s,则rk在右半区
图5.10 选择问题的减治思想
以5为轴值划分序列
4<5,只在左侧查找
5 3 8 1 4 6 2 3 4 1 5 6
9 2 7 9 8 7
以2为轴值划分序列
4>2,只在右侧查找 以4为轴值划分序列 4=4,轴值即为第4小元素 图5.11
选择问题
设无序序列T=(r1, r2, …, rn),T的第k(1≤k≤n) 小元素定义为T按升序排列后在第k个位置上的 元素。给定一个序列T和一个整数k,寻找T的 第k小元素的问题称为选择问题。特别地,将 寻找第n/2小元素的问题称为中值问题。 选择问题的一个很自然的想法是将序列T排序, 然后取第k个元素就是T的第k小元素。但是这 个算法的最好时间是O(nlog2n),应用减治技术 可以将算法的平均时间性能提高到O(n)。
a a n (a n 2 ) 2 ( n 1) 2 2 ) a ( a n 1 n 1且是偶数 n 1且是奇数
利用分治法,如果n=1,可以简单地返回a的值,如果n>1,可以把该问题分 解为两个子问题:计算前 n 2 个a的乘积和后 n 2 个 a的乘积,再把这两 个乘积相乘得到原问题的解。所以,应用分治技术得到如下计算方法:
排序问题中的减治法
堆排序
选择问题
堆排序
例
28 25 36 18 32 28 36 25 18 16 32 25 16 36 25 18 16 36 28 32
28
18 16
32
堆排序是利用堆(假设利用大根堆)的特性进 行排序的方法,其基本思想是:首先将待排序 的记录序列构造成一个堆,此时,选出了堆中 所有记录的最大者即堆顶记录,然后将它从堆 中移走(通常将堆顶记录和堆中最后一个记录 交换),并将剩余的记录再调整成堆,这样又 找出了次大的记录,以此类推,直到堆中只有 一个记录为止。
算法与算法复杂性
王 涛
长春工业大学
计算机科学与工程学院 wangtao690103@163.com
第五章
减 治 法
减治是基于变换的思想。 分两个阶段工作,即“变”阶段和“治”阶段. 变治法的三种类型: 1)实例化简(instance simplification) 2)改变表现(representation change) 3)问题化简(problem reduction)