算法设计与分析基础(五) 减治法
将规模为n的问题递减为规模为n-1或n/2的子问题, 反复递减后对子问题求解, 再建立子问题的解与原问题的解的关系。
减常量
插入排序
常用的插入排序有:直接插入排序、折半插入排序,它们划分的依据是在排好序的序列中寻找插入位置所使用方法的不同。
直接插入排序
-
伪代码实现 Algorithm InsertSort ( A[0..n-1] )
for i ← 1 to n-1 do
temp ← A[i];
j ← i-1;
while j ≥ 0 and A[j] > temp do
A[j+1] ← A[j];
j ← j –1;
end of while
A[j+1] ←temp;
end of for
-
效率分析 基本操作:比较 比较次数: 最坏的情形是: 严格递减的数组{ 90, 89, 68, 45, 34, 29, 17 }每次插入, 需比较已插入的所有元素, 此时, 第 i 次插入比较 i个元素, 故 最佳情况?升序排列 { 17, 29, 34, 45, 68, 89, 90 }每次插入只需比较一次 平均效率的精确分析基于对无序元素的研究,对于随机序列的数组
折半插入排序(属于减常因子部分,放在次数便于比较)
伪代码:
Algorithm InsertSort( A[0..n-1] )
1. for i ← 1 to n-1 do
1.1 temp ← A[i];
1.2 在有序序列A[0], A[1], ..., A[i-1]中使用
折半查找技术找到temp应该插入的位置,
并将temp插入使得A[0], A[1], ..., A[i-1] , A[i] 有序;
end of for
算法复杂度的对比
拓扑排序
拓扑排序问题:对给定的有向无环图,按照顺序列出它的顶点序列,该序列满足条件:每一条有向边的起点总在其终点之前。
求拓扑排序的算法:
应用DBS的出栈次序
减常因子
假币问题
有n个金币,其中一个是假币。这个假币的重量比真币的重量要轻一点,所有n-1个金币的重量是一样的。现在你有一架天平,设计高效的算法(用最少的使用天平次数)找出那个假的金币。
-
用减治法(n/2) -
用减治法(n/3)
折半查找
-
伪代码递归描述实现 BinarySearch ( l, r, x )
begin
m := └(l+r) /2┘;
case
x < A[m] : BinarySearch ( l, m-1, k );
x = A[m] : return (x, m);
x > A[m] : BinarySearch ( m+1 r, k ) ;
end of case
end.
-
伪代码循环实现 BinarySearch( A[0..n-1], x )
begin
l :=0, r :=n-1;
While l ≤ r do
m := └(l+r)/2┘;
if x = A[m] then return m
else if x < A[m] then r :=m-1
else l :=m+1;
return -1;
end
-
复杂度分析
|