第一篇:C語(yǔ)言常用算法歸納
C語(yǔ)言常用算法歸納
應(yīng)當(dāng)掌握的一般算法
一、基本算法:
交換、累加、累乘
二、非數(shù)值計(jì)算常用經(jīng)典算法:
窮舉、排序(冒泡,選擇)、查找(順序即線性)
三、數(shù)值計(jì)算常用經(jīng)典算法:
級(jí)數(shù)計(jì)算(直接、簡(jiǎn)接即遞推)、一元非線性方程求根(牛頓迭代法、二分法)、定積分計(jì)算(矩形法、梯形法)
四、其他:
迭代、進(jìn)制轉(zhuǎn)換、矩陣轉(zhuǎn)置、字符處理(統(tǒng)計(jì)、數(shù)字串、字母大小寫轉(zhuǎn)換、加密等)、整數(shù)各數(shù)位上數(shù)字的獲取、輾轉(zhuǎn)相除法求最大公約數(shù)(最小公倍數(shù))、求最值、判斷素?cái)?shù)(各種變形)、數(shù)組元素的插入(刪除)、二維數(shù)組的其他典型問(wèn)題(方陣的特點(diǎn)、楊輝三角形)
詳細(xì)講解
一、基本算法
1.交換(兩量交換借助第三者)
例
1、任意讀入兩個(gè)整數(shù),將二者的值交換后輸出。main(){ int a,b,t;
scanf(“%d%d”,&a,&b);
printf(“%d,%dn”,a,b);t=a;a=b;b=t;
printf(“%d,%dn”,a,b);} 1 【解析】程序中加粗部分為算法的核心,如同交換兩個(gè)杯子里的飲料,必須借助第三個(gè)空杯子。
假設(shè)輸入的值分別為3、7,則第一行輸出為3,7;第二行輸出為7,3。其中t為中間變量,起到“空杯子”的作用。
注意:三句賦值語(yǔ)句賦值號(hào)左右的各量之間的關(guān)系!
【應(yīng)用】
例
2、任意讀入三個(gè)整數(shù),然后按從小到大的順序輸出。main(){ int a,b,c,t;scanf(“%d%d%d”,&a,&b,&c);/*以下兩個(gè)if語(yǔ)句使得a中存放的數(shù)最小*/ if(a>b){ t=a;a=b;b=t;} if(a>c){ t=a;a=c;c=t;} /*以下if語(yǔ)句使得b中存放的數(shù)次小*/ if(b>c){ t=b;b=c;c=t;} printf(“%d,%d,%dn”,a,b,c);} 2.累加
累加算法的要領(lǐng)是形如“s=s+A”的累加式,此式必須出現(xiàn)在循環(huán)中才能被反復(fù)執(zhí)行,從而實(shí)現(xiàn)累加功能?!癆”通常是有規(guī)律變化的表達(dá)式,s在進(jìn)入循環(huán)前必須獲得合適的初值,通常為0。
例
1、求1+2+3+……+100的和。main(){ int i,s;s=0;i=1;while(i<=100){ s=s+i;/*累加式*/
i=i+1;/*特殊的累加式*/
}
printf(“1+2+3+...+100=%dn”,s);} 【解析】程序中加粗部分為累加式的典型形式,賦值號(hào)左右都出現(xiàn)的變量稱為累加器,其中“i = i + 1”為特殊的累加式,每次累加的值為1,這樣的累加器又稱為計(jì)數(shù)器。
3.累乘
累乘算法的要領(lǐng)是形如“s=s*A”的累乘式,此式必須出現(xiàn)在循環(huán)中才能被反復(fù)執(zhí)行,從而實(shí)現(xiàn)累乘功能?!癆”通常是有規(guī)律變化的表達(dá)式,s在進(jìn)入循環(huán)前必須獲得合適的初值,通常為1。
例
1、求10!
[分析] 10!=1×2×3×……×10
main(){ int i;long c;c=1;i=1;while(i<=10){ c=c*i;/*累乘式*/
i=i+1;} printf(“1*2*3*...*10=%ldn”,c);}
二、非數(shù)值計(jì)算常用經(jīng)典算法
1.窮舉
也稱為“枚舉法”,即將可能出現(xiàn)的每一種情況一一測(cè)試,判斷是否滿足條件,一般采用循環(huán)來(lái)實(shí)現(xiàn)。
例
1、用窮舉法輸出所有的水仙花數(shù)(即這樣的三位正整數(shù):其每位數(shù)位上的數(shù)字的立方和與該數(shù)相等,比如:1*1*1+5*5*5+3*3*3=153)。
[法一] main(){ int x,g,s,b;for(x=100;x<=999;x++){ g=x%10;s=x/10%10;b=x/100;
if(b*b*b+s*s*s+g*g*g==x)printf(“%dn”,x);} } 【解析】此方法是將100到999所有的三位正整數(shù)一一考察,即將每一個(gè)三位正整數(shù)的個(gè)位數(shù)、十位數(shù)、百位數(shù)一一求出(各數(shù)位上的數(shù)字的提取算法見下面的“數(shù)字處理”),算出三者的立方和,一旦與原數(shù)相等就輸出。共考慮了900個(gè)三位正整數(shù)。
[法二] main(){int g,s,b;for(b=1;b<=9;b++)for(s=0;s<=9;s++)for(g=0;g<=9;g++)
if(b*b*b+s*s*s+g*g*g==b*100+s*10+g)printf(“%dn”,b*100+s*10+g);} 【解析】此方法是用1到9做百位數(shù)字、0到9做十位和個(gè)位數(shù)字,將組成的三位正整數(shù)與每一組的三個(gè)數(shù)的立方和進(jìn)行比較,一旦相等就輸出。共考慮了900個(gè)組合(外循環(huán)單獨(dú)執(zhí)行的次數(shù)為9,兩個(gè)內(nèi)循環(huán)單獨(dú)執(zhí)行的次數(shù)分別為10次,故if語(yǔ)句被執(zhí)行的次數(shù)為9×10×10=900),即900個(gè)三位正整數(shù)。與法一判斷的次數(shù)一樣。
2.排序
(1)冒泡排序(起泡排序)
假設(shè)要對(duì)含有n個(gè)數(shù)的序列進(jìn)行升序排列,冒泡排序算法步驟是:
①?gòu)拇娣判蛄械臄?shù)組中的第一個(gè)元素開始到最后一個(gè)元素,依次對(duì)相鄰兩數(shù)進(jìn)行比較,若前者大后者小,則交換兩數(shù)的位置;
②第①趟結(jié)束后,最大數(shù)就存放到數(shù)組的最后一個(gè)元素里了,然后從第一個(gè)元素開始到倒數(shù)第二個(gè)元素,依次對(duì)相鄰兩數(shù)進(jìn)行比較,若前者大后者小,則交換兩數(shù)的位置;
③重復(fù)步驟①n-1趟,每趟比前一趟少比較一次,即可完成所求。例
1、任意讀入10個(gè)整數(shù),將其用冒泡法按升序排列后輸出。#define n 10 main(){ int a[n],i,j,t;for(i=0;i scanf(“%d”,&a[i]);for(j=1;j<=n-1;j++) /*n個(gè)數(shù)處理n-1趟*/ for(i=0;i<=n-1-j;i++)/*每趟比前一趟少比較一次*/ if(a[i]>a[i+1]){ t=a[i];a[i]=a[i+1];a[i+1]=t;} for(i=0;i (2)選擇法排序 選擇法排序是相對(duì)好理解的排序算法。假設(shè)要對(duì)含有n個(gè)數(shù)的序列進(jìn)行升序排列,算法步驟是: ①?gòu)臄?shù)組存放的n個(gè)數(shù)中找出最小數(shù)的下標(biāo)(算法見下面的“求最值”),然后將最小數(shù)與第1個(gè)數(shù)交換位置; ②除第1個(gè)數(shù)以外,再?gòu)钠溆鄋-1個(gè)數(shù)中找出最小數(shù)(即n個(gè)數(shù)中的次小數(shù))的下標(biāo),將此數(shù)與第2個(gè)數(shù)交換位置; ③重復(fù)步驟①n-1趟,即可完成所求。 例 1、任意讀入10個(gè)整數(shù),將其用選擇法按升序排列后輸出。#define n 10 main(){ int a[n],i,j,k,t;for(i=0;i if(a[j] < a[k])k = j; if(k!= i){ t = a[i];a[i] = a[k];a[k] = t;} } for(i=0;i printf(“%dn”,a[i]);} (3)插入法排序 要想很好地掌握此算法,先請(qǐng)了解“有序序列的插入算法”,就是將某數(shù)據(jù)插入到一個(gè)有序序列后,該序列仍然有序。插入算法參見下面的“數(shù)組元素的插入”。 例 1、將任意讀入的整數(shù)x插入一升序數(shù)列后,數(shù)列仍按升序排列。#define n 10 main(){ int a[n]={-1,3,6,9,13,22,27,32,49},x,j,k; /*注意留一個(gè)空間給待插數(shù)*/ scanf(“%d”,&x);if(x>a[n-2])a[n-1]=x; /*比最后一個(gè)數(shù)還大就往最后一個(gè)元素中存放*/ else /*查找待插位置*/ { j=0; while(j<=n-2 && x>a[j])j++; for(k=n-2;k>=j;k--)/*從最后一個(gè)數(shù)開始直到待插位置上的數(shù)依次后移一位*/ a[k+1]=a[k]; a[j]=x; /*插入待插數(shù)*/ } for(j=0;j<=n-1;j++)printf(“%d ”,a[j]);} 插入法排序的要領(lǐng)就是每讀入一個(gè)數(shù)立即插入到最終存放的數(shù)組中,每次插入都使得該數(shù)組有序。 例 2、任意讀入10個(gè)整數(shù),將其用插入法按降序排列后輸出。(提示:將第2至第10個(gè)數(shù)一一有序插入到數(shù)組a中)#define n 10 main(){ int a[n],i,j,k,x;scanf(“%d”,&a[0]);/*讀入第一個(gè)數(shù),直接存到a[0]中*/ for(j=1;j { scanf(“%d”,&x);