算法导论 第1、2、3章 算法基础
算法导论 第1、2、3章 算法基础
第1章 算法在计算中的作用
算法 就是任何良定义的计算过程,该过程取某个值或值的集合作为输入并产生某个值或值的集合作为输出。
第2章 算法基础
排序问题:
插入排序 即不断地将下一个数字插入到已排序的数列中对应的位置:
包含元素1~j-1的子数组构成了当前已排序好的数字,剩余的子数组对应剩下待插入的数字。
循环不变式 用于证明算法的正确性,三条性质:
- 初始化:循环的第一次迭代前为真
- 保持:若循环的某次迭代前为真,则下次迭代前仍为真
- 终止:循环终止时,不变式提供一个有用的性质,有助于证明算法是正确的
对于插入排序,初始化时已排序子数组只有一个元素,成立。每次插入新数字后子数组依然有序,成立。循环终止时获得了已排序的整个数组,成立。因此算法正确。
算法的 运行时间 指执行的基本操作数或步数。
对于插入排序,假定各语句的代价为ci:
算法的总运行时间:
若出现最佳情况,即输入数组已排好序,则运行时间为n的线性函数:
若出现最坏情况,即输入数组已反向排序,则运行时间为n的二次函数:
运行事件的增长率或增长量级只考虑公式中最重要的项,如二次项,因为n很大时低阶项相对并不重要。记插入排序的最坏情况运行时间为Θ(n2)。
若一个算法的最坏情况运行时间比另一个算法有更低的增长量级,则认为该算法更有效。
分治法 是指将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解。其步骤分为:
- 分解为若干子问题
- 递归地解决子问题
- 合并为原问题的解
归并排序 是一种遵循分治模式的排序算法,将待排序的序列分解成两个子序列,递归地使用这种方法排序子序列,最终合并已排序的子序列。
首先定义合并过程,通过不断取两个已排序数组的第一个元素中较小的一个来实现:
合并过程的运行时间是Θ(n),因为其中的for循环需要Θ(n)时间,其他语句需要常量时间。
将合并过程作为归并排序的子程序,递归地完成整个排序过程:
归并排序的最坏情况运行时间T(n):
- 分解步骤需要常量时间Θ(1)
- 递归求解子问题,需要2T(n/2)的时间
- 合并需要Θ(n)
相加得到:
由递归树具有lgn+1层(lgn即log2n),每层代价为cn,可得总代价为cnlgn+cn,即Θ(nlgn)。
第3章 函数的增长
我们使用 渐近记号 来描述算法的运行时间。
- Θ记号:渐近紧确界,类似=
- O记号:渐近上届,类似<=
- Ω记号:渐近下届,类似>=
- o记号:非渐近紧确的上届,类似<
- ω记号:非渐近紧确的下届,类似>
对任意两个函数f(n)和g(n),有f(n)=Θ(g(n)),当且仅当f(n)=O(g(n))且f(n)=Ω(g(n))。