- 学习目标
- 设计高效的算法
- 分析算法的性能
- 在分析与交互中验证算法
- 参考书:算法导论
1、算法定义
- 算法定义:给定计算问题,算法是一系列良定义的计算步骤,逐一执行计算步骤即可得到预期的输出。
- 计算问题:给定数据输入,计算满足某种性质输出问题
- 算法的性质
- 有穷性:算法必须在有限个计算步骤后终止。
- 确定性:算法必须是没有歧义的。
- 可行性:可以机械的一步一步执行基本的操作步骤。
2、算法的表示
- 自然语言
- 优势:以近于人的思维,易于理解主旨
- 编程语言
- 优势:精准表达逻辑,规避表述歧义
- 不便之处:不同的编程语言间语法存在差异,过于关注算法实现的细枝末节
- 伪代码
- 非正式语言
- 移植编程语言书写形式作为基础和框架
- 按照接近自然语言的形式表达算法过程
- 兼顾自然语言与编程语言优势
- 简洁表达算法本质,不拘泥于实现细节
- 准确反映算法过程,不产生矛盾和歧义
- 非正式语言
3、算法分析
-
算法分析的原则
- 统一机器性能
- 分析最坏情况
-
机器的运算速度影响算法的执行时间
- 归纳基本操作
- 统一机器性能
-
相同的输入规模,实例影响运行
- 例:插入排序(升序排序)最好情况:数组升序,最坏情况:数组降序
- 例:插入排序(升序排序)最好情况:数组升序,最坏情况:数组降序
-
算法分析的工具
- 渐近分析:忽略
T
(
n
)
T(n)
T(n)的系数与低阶项,仅关注高阶项,用记号
θ
\theta
θ表示
- 渐近记号
- 渐近紧确界
- 渐近上界
- 渐近下界
- 渐近分析:忽略
T
(
n
)
T(n)
T(n)的系数与低阶项,仅关注高阶项,用记号
θ
\theta
θ表示
4、例子
- 插入排序与选择排序
- 伪代码及时间复杂度分析
- 伪代码及时间复杂度分析
- 代码实现
# 插入排序:将数组a分为有序和无序的两个部分。前者在左边,后者在右边。开始有序的部分只有a[0],其余都属于无序的部分。
# 每次取出无序部分的第一个(最左边)元素,把它加入有序部分。假设插入合适的位置p,则原p位置及其后面的有序元素都向右移动一个位置,
# 有序部分增加一个元素。一直做下去,直到无序部分没有元素
def insert_sort(l):
for i in range(len(l) - 1):
key = l[i+1] # 无序部分第一个值
index = i
while index >= 0 and l[index] > key:
l[index+1] = l[index]
index -= 1
l[index + 1] = key
return l
# 选择排序:每次从待排序列中选出一个最小值
def select_sort(l):
for i in range(len(l)):
for j in range(i+1, len(l)):
if l[i] > l[j]:
temp = l[i]
l[i] = l[j]
l[j] = temp
return l