算法設計與分析-第三版-呂國英


算法設計與分析

第一章、算法概述

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