目录
【例2-11】对于任意给定的n阶方阵A和B,求A×B的积C并且 分析它算法执行效率。
非递归形式算法分析:
递归形式算法分析:
【例2-9】交换a和b的值。
非递归
算法设计与描述 | 算法分析 |
输入:a,b | (1)输入a,b两个数,规模为2 |
输出:a,b | |
swap(a,b) { a <- b; b <- Temp; output(a,b); } | (2)核心操作为3条交换语句; (3)核心操作执行的次数是一个与输入规模无关的常数 (4)算法的时间复杂度为常数阶 T(n)= O(1) //O渐近上界 0 ≤ f(n) ≤ c*g (n ) |
【例2-10】求n!
非递归:
算法设计与描述 | 算法分析 |
输入:n | (1)输入n,规模为n ,控制迭代次数。 |
输出:n ! | |
F (n) { for i <- 1 to n do s=s*i ; output(s); } | (2)核心操作为 s=s*i ; 一次乘法运算 (3)核心操作执行的次数,只受输入规模n控制 (4)依据定理2.5 算法的时间复杂度为常数阶 T(n)= ∑(n,i=1) 1 = Θ(n) //渐近紧界 |
算法设计与描述 | 算法分析 |
输入:n | (1)输入n,规模为n ,计算规模也是n |
输出:n ! | |
F (n) { else return n*F(n-1); } | (2)核心操作为 n*F(n-1) ; 一次乘法运算 (3)根据递推公式,每递推一次,执行一次乘法操作,因此有以下推导过程: (4) //渐近紧界 |
思考题:韩信点兵
#include<iostream>
using namespace std;
int main()
{
int n=1;
while( (n%3!=2)||(n%5!=3)||(n%7!=2)){
n++;
}
cout<<n;//23
return 0;
}
优化:
//a,b,c中,c的大小对该结果影响最大,因此从c入手可以稍微提高运算效率。
void hanxin01()
{
int n=9;//7+2
int i=0;
while(true)
{
if(n%3==2&&n%5==3)
break;
i++;
n+=7;
}
cout<<"次数:"<<i<<"结果"<<n<<endl;
}
【例2-11】对于任意给定的n阶方阵A和B,求A×B的积C并且 分析它算法执行效率。
问题分析:
C也是n阶方阵,每个元素 = 矩阵A的行 和矩阵B的列 的点积 。
对于 i>=0 , j<= n-1 的每一对下标 ,有 C[i,j] = A[i,0]B[0,j] +... + [i,k]B[k,j] + .... + A[i,n-1]B[n-1,j]
计算模型:
非递归:
算法设计与描述 | 算法分析 |
输入:A,B | (1)输入A,B,规模为n x n |
输出:C=Ax B | |
MatrixMultiplication (A[n] ,B[n] ) { for i <- 0 to n-1 do for j <- 0 to n-1 do { C[i,j] <- 0.0 ; for k <- 0 to n-1 do C[i,j] = C[i,j] + A[i,k]*B[k,j]; } return C; } | (2)核心操作 通过加法和乘法运算 求C[i,j] (3)核心操作执行的次数,只受输入规模n控制 ∑(n-1 , k=0) 1 (4)依据定理2.5 算法的时间复杂度为常数阶 T(n)= Θ(n^3 ) //渐近紧界 |
【例2-13】汉诺塔(Tower of Hanoi)问题。
问题分析:
计算规模:
递归:
算法设计与描述 | 算法分析 |
输入:n | (1)输入n,计算规模是n |
输出:显示 | |
Hanoi (A,C,n) { else { Hanio(A,B,n-1);//n-1个盘子,从A移到B,借助另一个 move(A,C); // 从A移动到C Hanoi(B,C,n-1); // } } | (2)核心操作为 移动盘子 (3)根据递推公式,。。。【不全】
|
【例2-14】试分析二路归并排序算法的时间复杂度。
问题分析:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
//二路归并
int a[100];
int n=10;
void merge(int a[],int low,int mid,int high)
{
int sum1=mid-low+1;//元素个数
int sum2=high-mid;
int b[100]={0};
int c[100]={0};
for(int i=0;i<sum1;i++)
{
b[i]=a[i+low];
}
for(int i=0;i<sum2;i++)
{
c[i]=a[i+mid+1];
}
//
int i=0,j=0;
int k=low;
while(i<sum1&&j<sum2)
{
//先从数组中找出较小的值
if(b[i]<=c[j])
{
a[k]=b[i];
i++;
}
else
{
a[k]=c[j];
j++;
}
k++;
}
//如果有剩余
if(i>sum1)//c有剩余
{
for(;j<sum2;j++,k++)
{
a[k]=c[j];
}
}
else
{
for(;i<sum1;i++,k++)
{
a[k]=b[i];
}
}
}
void mergesort(int a[],int low,int high)
{
int mid;
if(low<high)
{
mid=(low+high)/2;
mergesort(a,low,mid);
mergesort(a,mid+1,high);
merge(a,low,mid,high);
}
}
void init(int a[])
{
srand(time(0));
for(int i=0;i<n;i++)
{
a[i]=rand()%100;
}
}
void show()
{
for(int i=0;i<n;i++)
{
cout<<a[i]<<"\t";
}
cout<<endl;
}
int main()
{
init(a);
show();
mergesort(a,0,n-1);
show();
return 0;
}
算法设计与描述 MergeSort( A,p,r ) | 算法分析【换元迭代】 |
输入:n个数的无序序列A[p,r] , 1<= p <= r <= n , | (1)输入n,计算规模是n |
输出:n个数的有序序列A[p,r] | |
MergeSort (A,p,r) { { q <- (p+r)/2 ;//中间 MergeSort (A,p,q); //左侧 MergeSort(A,q+1,r) ;//右侧 Merge (A,p,q,r); } } | (2)核心操作为 移动盘子 (3) (4) 换元 |
代码代码
Merge
算法设计与描述 Merge( A,p,q,r ) | 算法分析 |
输入:n按递增顺序排好的 A[p...q] 和 A[q+1...r ] | (1)输入n,计算规模是n |
输出:按照递增顺序排序的A[p,r] | |
Merge (A,p,q,r) { x <- q-p+1 ,y <- r-q;//x,y分别是两个子数组的元素数 A[p...q] -> B[1...x] , A[q+1...r] -> C[1...y] //两个新数组 i <- 1 ,j<- 1 ,k <- p while i<=x and j <= y do { if ( B[i] <= C[ j ] ) //注意是i 和 j { A[k] <- B[i];//较小数 i <- i+1; } else { A[k] <- C[j] ; j <- j+1; } k=k+1; } if(i>x) C[j...y] -> A[k..r] //如果还要剩余的元素,就不需要比较,直接赋值回去就行 else B[i..x] -> A[k...r] } | (2)核心操作为 移动盘子 (3)根据递推公式,。。。【不全】 |