算法设计与分析-第三版-吕国英


算法设计与分析

第一章、算法概述

1。用计算机求解问题的步骤

答:1、问题分析
2、数学模型建立
3、算法设计与选择
4、算法表示
5、算法分析
6、算法实现
7、程序测试及调试
8、结果整理文档编制

2、算法的定义

答:算法是指在解决问题时,按照某种机械步骤一定可以得到问题结果的处理过程

所谓机械步骤是指,算法中有待执行的运算和操作,必须是相当基本的

3、算法的三要素

答:算法由操作、控制结构、数据结构3要素组成

操作:算术运算、关系运算、逻辑运算、数据传送

控制结构:顺序结构、选择结构、循环结构(递归机制)

数据结构:数据间的逻辑关系、数据的存储方式几处理方式就是数据的数据结构

4、算法的基本性质

答:目的性、分布性、有序性、有限性、操作性

5、算法的基本特征

答:有穷性、确定性、可行性、算法有零个或多个的输入、算法有一个或多个的输出

6、算法的质量指标 ★★

答:正确性、可读性、稳健性、高效率与低存储量需求

7、结构化方法

答:自顶向下、逐步求精、模块化

【例】求两个正整数的最大公约数

int main(void)
{
    int a, b, t, i;
    scanf("请输入两个数%d,%d", &a, &b);
    t = 1;
    for (i = 2; i <= a || i <= b; i = i + 1)
        while (a % i == 0 || b % i == 0)
        {
            t = t * i;
            a = a / i;
            b = b / i;
        }
    printf("%d,%d maximal common divisor is %d", a, b, t);
}

第二章、算法分析基础

1、算法的分析和评价 ★

答:对于算法的分析和评价,一般考虑正确性、可维护性、可读性、运算量、占用存储控件等因素,其中评价算法的3条重要指标是:

(1)算法实现所耗费的时间;

(2)算法实现所耗费的存储空间,其中主要考虑辅助存储空间;

(3)算法应易于理解、易于编码、易于调试等;

2、与算法执行时间相关的因素

答:

问题中数据存储的数据结构。

算法采用的数学模型

算法设计的策略

问题的规模

实现算法的程序设计语言

编译算法产生的机器代码的质量

计算机执行指令的速度

3、频度:语句的频度是指该语句重复执行的次数

4、算法的储存量包括

答:

输入数据所占空间;

算法(程序)本身所占空间;

辅助变量所占空间。

第三章、算法基本工具和优化技巧

1、递归设计要点:

答:

分析问题、寻找递归关系:找出大规模问题与小规模问题的关系,这样通过递归使问题的规模逐渐变小。

设置边界、控制递归:找出停止条件,即算法可解的最小规模问题。

设计函数、确定参数:和其他算法模块一样设计函数体中的操作及相关参数。

2、什么是数学模型:

答:数学模型是利用数学语言(符号、式子与图像)模拟现实的模型。把现实模型抽象、简化为某种数学结构是数学模型的基本特征。

【例1】求1/1!-1/3!+1/5!-1/7!+...+(-1)n+1/(an-1)!

main()
	{
	int i,n,j,sign=1;
	float s,t=1;
		input(n);
		s=1;
	for(i=2;i<=n;i=i+1)
		{
		t=1;
		for(j=1;j<=2*2-1;j=j+1)
			t=t*j;
		sign=1;
		for(j=1;j<=i+1;j=j+1)
			sign=sign*(-1);
		s=s+sign/t;
		}
		print("Sum=",s);
	}

【例2】编写算法:打印具有下面规律的图形。

1
5 2
8 6 3
10 9 7 4

main ()
{
    int i,j,a[100][100],n,k;
    input(n);
    k=1;
    for(i=1;i<=n;i=i+1)
        for(j=1;j<=n+1-i;j=j+1)
        {
            a[i-1+j][j]=k;
            k=k+1;
        }
    for(i=1;i<=n;i=i+1)
    {
        print('换行符');
        for(j=1;j<=i;j+j+1)
            print(a[i][j]);
    }
}

【例3】任给十进制的正整数,请从低位到高位逐位输出各数字。

循环算法:

main()
{
    int n;
    input(n);
    while (n>=10)
    {
        print(n mod 10);
        n=n\10;
    }
    print(n);
}

递归算法:

main()
{
    int n;
    input (n);
    f(n);
}
f(int n)
{
    if(n<10)
        print(n);
    else
    {
        print(n mod 10);
        f(n\10);
    }
}

【例4】开灯问题

main()
{
    int n,a[1000],i,k;
    print("input a number");
    input(n);
    for (i=1;i<=n;i=i+1)
        a[i]=0;
    for (i=2;i<=n;i=i+1)
    {
        k=1;
        while (i*k<=n)
        {
            a[i*k]=1-a[i*k];
            k=k+1;
        }
    }
    for (i=1;i<=n;i=i+1)
        if (a[i]=1)
            print(i);
}

【例5】抓小偷问题

main()
{
    int x;
    for(x=1;x<=4;x=x+1)
        if((x<>1)+(x=3)+(x=4)+(x<>4)=3)
            print(chr(64+x),"is a thief");
}

【例6】编写算法对输入的整数进行判断能否被3,5,7整除,并输出以下信息

main()
{
    long n;
    int k;
    print("please enter a number:");
    input(n);
    k=(n mod 3=0)+(n mod 5=0)+(n mod 7=0)
        switch(k)
        {
            case 3:print('all');break;
            case 2:print('two');break;
            case 1:print('one');break;
            case 0:print('none');break;
        }
}

第四章、基本的算法策略

1、迭代算法

答:迭代法也称“辗转法”,是一种不断用变量的旧值递推出新值的解决问题的方法。(累加、累乘、阶乘)

2、推倒法

答:推倒法是对某些特殊问题所采用的违反通常习惯的,从后向前解问题的方法。

3、枚举法

答:枚举法(穷举法)是蛮力策略的一种表现形式,也是一种使用非常普遍的思维方法。它是根据问题中的条件将可能的情况一一列举出来,逐一尝试从中找出满足问题条件的解。

4、贪婪算法

答:贪婪法又叫登山法,他的根本思想是逐步到达山顶,即逐步获得最优解,是解决最优化问题时的一种简答但适用范围有限的策略。

5、设计动态规划算法的基本步骤

答:1、划分阶段 2、选择状态 3、确定决策并写出状态转移方程

实际应用中可以安装一下简化步骤设计:

(1)分析最优解的性质,并刻画其结构特征。

(2)递推定义最优值。

(3)已自底向上的方式或自顶向下的记忆化方法(备忘录法)计算出最优值。

(4)根据计算最优值时得到的信息,构造问题的最优解。

【例1】兔子繁殖问题(斐波那契数列)

算法1:

main(){    int i,a=1,b=1;    print(a,b);    for (i=1;i<=10;i=i+1)    {        c=a+b;        print(c);        a=b;        b=c;    }}

算法2:

main(){    int i,a=1,b=1;    print(a,b);    for (i=1;i<=4;i=i+1)    {        c=a+b;        a=b+c;        b=a+c;        print(a,b,c);    }}

算法3:

main(){    int i,a=1,b=1;    print(a,b);    for (i=1;i<=5;i=i+1)    {        a=a+b;        b=a+b;        print(a,b)    }}

【例2】求两个整数的最大公约数(辗转相除法)

main(){    int a,b;    input(a,b);    if (b=0)    {        print("data error");        return;    }    else    {        c=a mod b;        while c<>0        {            a=b;            b=c;            c=a mod b;        }    }    print(b);}

【例3】猴子吃桃问题

main(){    int i,a;    a=1;    for (i=9;i>=1;i=i-1)        a=(a+1)*2;    print(a);}

【例4】杨辉三角

main(){    int n,i,j,a[100];    input(n);    print('1');    print('换行符');    a[1]=a[2]=1;    print(a[1],a[2]);    print('换行符');    for (i=3;i<=n;i=i+1)    {        a[1]=a[i]=1;        for (j=i-1;j>1,j=j-1)            a[j]=a[j]+a[j-i];        for (j=1;j<=i;j=j+1)            print(a[j]);        print('换行符');    }}

【例5】牛顿迭代法。

利用牛顿迭代法,求ax3+bx2+cx+d=0的根。

main(){    float a,b,c,d,fx;    print('输入系数a,b,c,d:');    input(a,b,c,d);    fx=f(a,b,c,d);    print('方程的根为:',fx);}float f(a,b,c,d)float a,b,c,d;{    float x1=1,x0,f0,f1;    do    {        x0=x1;        f0=((a*x0+b)*x0+c)*x0+d;        f1=(3*a*x0+2*b)*x0+c;        x1=x0-f0/f1;    }    while (fabs(x1-x0)>=1e-4);return(x1);}

【例6】二分法求解方程f(x)=0的根

main(){    float x,x1=0,x2=2,f1,f2,f;    print("input x1,x2(f(x1)*f(x2)<0)");    input(x1,x2);    f1=x1*x1*x1/x2+2*x1*x1-8;    f2=x2*x2*x2/x2+2*x2*x2-8;    if (f1*f2>0)    {        print("Non root");        return;    }    do    {        x=(x1+x2)/2;        f=x*x*x/2+2*x*x-8;        if(f=0) break;        if(f1*f>0.0)        {            x1=x;            f1=f;        }        else            x2=x;    }    while (fabs(f)>=1e-4);    print('root=',x);}

【例7】金块问题

maxmin(float a[],int n){    max=a[1];    min=a[1];    for (i=2;i<=n;i=i+1)        if(max<a[i])            max=a[i];    	else             if(min>a[i])                min=a[i];}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM