Multiply(x,y,n): if n==1: return x*y a = x/pow(10,n/2) b = x%pow(10,n/2) c = y/pow(10,n/2) d = y%pow(10,n/2) ac = Multiply(a,c,n/2) ad = Multiply(a,d,n/2) cb = Multiply(c,b,n/2) bd = Multiply(b,d,n/2) xy = ac*pow(10,n)+(ad+cb)*pow(10,n/2)+bd return xy
Karatsuba乘法
两个位数乘法分治成三个位数乘法,复杂度变为,有所改善
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Multiply(x,y,n): if n==1: return x*y a = x/pow(10,n/2) b = x%pow(10,n/2) c = y/pow(10,n/2) d = y%pow(10,n/2)
ac = Multiply(a,c,n/2) bd = Multiply(b,d,n/2) z = Multiply(a+b,c+d,n/2)
defInsertionSort(A): for i inrange(1,len(A)): current = A[i] j = i-1 while j >= 0and A[j] > current: A[j+1] = A[j] j -= 1 A[j+1] = current
算法复杂度渐进性分析
表示上界
等价于
存在,使得任意,都有
表示下界
等价于
存在,使得任意,都有
表示上界和下界
等价于
且
证明方法
证明:提出和满足定义
证明:
令
则对于任意,
证明不是,反证法:假设存在一个和一个满足定义,通过推导出一个矛盾来证明
证明:对任意,不是
假设是,则存在,使得对任意,都有
则对任意,都有,当时显然不成立,产生矛盾。
对于,既没有,也没有。
只要保证随着的增大,和之间的关系忽大忽小即可。
算法分析的三个指导原则
最坏情况分析
忽略常数因子和低阶项
渐进分析
lecture2
Mergesort归并排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
MergeSort(A): n = length(A) if(n <= 1) return A L = MergeSort(A[0:n/2]) R = MergeSort(A[n/2:n]) return Merge(L,R)
Merge(L,R): n = length(L) + length(R) A[n], i = 0, j = 0 for k in range(0,n): if L[i] < R[j]: A[k] = L[i], i = i + 1 else: A[k] = R[j], j = j + 1 return A
Select(A,k): If len(A) <= 50: A = MergeSort(A) Return A[k-1] p = getPivot(A) // return some pivot L, pivotVal, R = Partition(A,p) // split up A to L,A[p],R if len(L) == k-1: return pivotVal else if len(L) > k-1: return Select(L, k) else if len(L) < k-1: return Select(R, k – len(L) – 1)
运行时间受pivot位置的影响
理想的pivot
基于MergeSort:选取最中间的数当pivot(假设可以选出),由主定理可证明,时间复杂度为
RSelect:在A中均匀随机地选取pivot
最坏情况下时间复杂度为
虽然最坏情况下时间复杂度为,但平均性能比基于MergeSort的方法还好
DSelect:选取中位数当pivot
只要这个pivot不要太偏两边即可:,
分成组,每组5个。先在每组中寻找中位数,再在这个中位数中寻找中位数。最终这个中位数即为pivot。
替换法证明渐进复杂度
猜测
假设,有
化简得,.令即可得证
怎么来的
:子数组个数(5个数一组)
:大于pivot的数的最大个数
对于m个数一组
例如:
时,
时,
时,
lecture4
BogoSort
1 2 3 4 5
BogoSort(A): while true: 随机排列A if(A is sorted) return A