绪论
绪论上
- Hailstone序列
int Hailstone(int n)
{
int nLen = 1;
while(1<n)
{
(n%2)?n = 3*n+1 : n =n/2;//条件?结果1:结果2
// if(n%2)
// n = 3*n+1;
// else
// n=n/2;
nLen++;
}
return nLen;
}
- 好算法:Algorithms + Data Structures = Programs 效率
- 度量:运行时间&存储空间
- 图灵机:比特纸带&读写头、二进制非负整数加一
- RAM模型:寄存器&汇编、运行时间->运行次数、向下取整的除法
绪论下
算法分析
- 迭代:级数求和
- 递归:递归跟踪+递推方程
- 猜测+验证
级数
- 算数级数:与末项平方同阶
- 幂方级数:比幂次高出一阶
- 几何级数:与末项同阶
- 收敛级数
- 长度有限级数
- 冒泡排序
估算
迭代与递归
减而治之策略
递归跟踪
适用简明递归
int sum(int A[],int n)
{
return (n<1) ? 0 : sum(A,n-1)+A[n-1];//计算算法复杂度时不计sum本身而计sum的表达子式,划掉sum 即可
}
递推方程
适用复杂递归
数组倒置实例
void reverse(int* A,int lo,int hi)//统一接口
{
if(A[lo] < A[hi])//规模奇偶性不变
{
swap(A[lo],A[hi]);
reverse(A,lo+1,hi-1);
}
else
return;//递归基
}
分而治之策略
二分递归
int sum(int A[],int lo,int hi)
{
if(lo == hi)
return A[lo];
int mi = (lo + hi) >> 1;
return sum(A,lo,mi) + sum(A,mi+1,hi);
}
递归+分治
求第一、第二大
动态规划
斐波拉数列
二分递归
#include <iostream>
int64_t fib ( int n ) { //计算Fibonacci数列的第n项(二分递归版):O(2^n)
return ( 2 > n ) ?
( int64_t ) n //若到达递归基,直接取值
: fib ( n - 1 ) + fib ( n - 2 ); //否则,递归计算前两项,其和即为正解
}
线性递归
#include <iostream>
int64_t fib ( int n, int64_t& prev ) {
if ( 0 == n ) //若到达递归基,则
{ prev = 1; return 0; } //直接取值:fib(-1) = 1, fib(0) = 0
else { //否则
int64_t prevPrev; prev = fib ( n - 1, prevPrev ); //递归计算前两项
return prevPrev + prev; //其和即为正解
}
} //用辅助变量记录前一项,返回数列的当前项,O(n)
迭代
#include <iostream>
int64_t fibI ( int n ) { //O(n)
int64_t f = 1, g = 0; //初始化:fib(-1)、fib(0)
while ( 0 < n-- ) { g += f; f = g - f; } //依据原始定义,通过n次加法和减法计算fib(n)
return g; //返回
}
最长公共子序列
递归
序列A[0,n] B[0,m]
递归基:
n = -1 或 m = -1, 空序列(为什么不是0?)
三种情况:
- 若A[n] = ‘X’ = B[m], 取 LCS(A[0,n) , B[0,m)) + ‘X’
- 若A[n] != B[m], 则在 LCS(A[0,n] , B[0,m)) 与 LCS(A[0,n) , B[0,m]) 中取更长者