版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
C程序設(shè)計(jì)專題輔導(dǎo)課
算法基礎(chǔ)
內(nèi)容提要:算法(algorithm)的概念算法的表達(dá)典型算法及其實(shí)現(xiàn)—排序查找其它算法一、算法的概念1.1算法是什么?1.2算法的五個要素1.3簡單算法-程序的例子1.1算法是什么?算法:解決特定類型問題的方法和步驟著名的Wirth公式:數(shù)據(jù)結(jié)構(gòu)+算法=程序1.1算法是什么?(續(xù))算法程序邏輯描述解決問題的思想方法:步驟描述用某語言表達(dá)的算法過程:指令集合問題解決問題的數(shù)據(jù)表示(數(shù)據(jù)結(jié)構(gòu))1.2算法的五個要素確定性:對同一個算法,相同的輸入應(yīng)該得到相同的輸出,不會因?yàn)椴煌臋C(jī)器和不同時間運(yùn)行而不同有窮性:算法中的步驟應(yīng)該是有限的,否則計(jì)算機(jī)就會永遠(yuǎn)無休止地執(zhí)行程序有效性:算法中的每一個步驟都應(yīng)該能被有效地執(zhí)行,并應(yīng)能得到一個明確的結(jié)果(大象裝入冰箱的問題)輸入:有零個或多個輸出:有一個或多個
1.3簡單算法-程序的例子歐幾里德(Euclid)算法:求兩個正整數(shù)A和B的最大公約數(shù)計(jì)算過程舉例:設(shè)A=18B=30①A=30B=18②C=A%B=12③A=18B=12④C=A%B=6⑤A=12B=6⑥C=A%B=0⑦最大公約數(shù)就是B=6第一步:比較A和B這兩個數(shù):A設(shè)置為較大的數(shù),B為較小的數(shù);第二步:A除以B,得到余數(shù)C;第三步:如果C等于0,則最大公約數(shù)就是B,算法結(jié)束;否則將B賦值給A,C賦值給B;第四步:重復(fù)進(jìn)行第二步、第三步。int
Euclid(inta,intb){intc;
if(a<b){c=a;a=b;b=c;}
while(c=a%b){a=b;b=c;}returnb;}二、算法的表達(dá)2.1用自然語言描述算法2.2用流程圖描述算法2.3用偽代碼描述算法2.1用自然語言描述算法問題:判斷一個正整數(shù)n是否為素?cái)?shù)的算法。算法描述一:將n作為被除數(shù),用2到n平方根的各個整數(shù)輪流去除,如果都不能整除,則n是素?cái)?shù);否則n不是素?cái)?shù)。算法描述二:第一步:輸入n的值,計(jì)算n的平方根m;第二步:j=2(用j去除n);第三步:n被j除,得到余數(shù)a;第四步:如果a==0,表示n能被j整除,
顯示信息“n不是素?cái)?shù)”,算法結(jié)束;
否則進(jìn)入下一步;第五步:將j加1送回給j;第六步:如果j<=m,則跳到第三步執(zhí)行;
否則顯示“n是素?cái)?shù)”的信息,算法結(jié)束。2.2用流程圖描述算法2.3用偽代碼描述算法int
prime(intn){m=n的開方;for(j=2;j<=m;j++){if(n被j整除)
break;}if(j>m)return1;/*是素?cái)?shù)*/elsereturn0;
/*不是素?cái)?shù)*/}歐幾里德(Euclid)算法:int
Euclid(inta,intb){if(a<b
)交換a和b;c=
a除以b的余數(shù);while(c!=0){a=b;b=c;c=
a除以b的余數(shù);}
returnb;
/*最大公因子*/}三、典型算法及其實(shí)現(xiàn)3.1排序算法
3.2查找算法
3.3常用算法舉例
3.1排序算法1、選擇排序2、冒泡排序3、插入排序4、*歸并排序問題:給定n個元素的數(shù)組a,對其中的元素從小到大排序,結(jié)果仍然在數(shù)組a中。排序算法-選擇排序35281設(shè)n=5;5個數(shù)是:35281(1)15283(2)2583(3)385(4)58排序算法-冒泡排序35281設(shè)n=5;5個數(shù)是:35281(1)3
2
5
1
8
(2)2
3
1
5
8
(3)2
1358
(4)1
2
358冒泡排序(偽代碼算法)voidBubbleSort(inta[],intn){
for(end=n-1;end>0;end--){
for(i=0;i<end;i++)if(
a[i]>a[i+1]){交換a[i]和a[i+1];}}
}
Entern:5Enter10integers:35281Aftersorted:12358排序算法-插入排序void
InsertionSort(inta[],intN){
intj,P;
int
Tmp;
for(P=1;P<N;P++){
Tmp=a[P];/*下一個元素*/
for(j=P;j>0&&a[j-1]>Tmp;j--) a[j]=a[j-1]; /*前面已排序的部分元素后移,在合適地方的給新元素留出位置*/ a[j]=Tmp;/*新來元素放入合適的位置*/}/*for-P循環(huán)結(jié)束*/}排序算法-插入排序35281設(shè)n=5;5個數(shù)是:35281(1)3(2)3
5(3)23
5(4)23
5
8(5)123
5
8
1、合并兩個有序序列:1132426215273812AptrBptrCptrAptrCptrBptrCptr排序算法-歸并排序void
MSort(intA[],int
TmpArray[],intLeft,intRight){
intCenter;
if(Left<Right){/*還有元素需要排序*/ Center=(Left+Right)/2;
MSort(A,TmpArray,Left,Center);
MSort(A,TmpArray,Center+1,Right);
Merge(A,TmpArray,Left,Center+1,Right);}}void
Mergesort(intA[],intN){
int
TmpArray[MAXSIZE];/*臨時工作空間*/
MSort(A,TmpArray,0,N-1);
}2、遞歸歸并排序算法/*Lpos=左半邊起始位置,Rpos=右半邊起始位置*/void
Merge(intA[],int
TmpArray[],int
Lpos,int
Rpos,int
RightEnd){
inti,LeftEnd,NumElements,TmpPos;
LeftEnd=Rpos-1;
TmpPos=Lpos;
NumElements=RightEnd-Lpos+1;
while(Lpos<=LeftEnd&&Rpos<=RightEnd)/*mainloop*/
if(A[Lpos]<=A[Rpos])
TmpArray[TmpPos++]=A[Lpos++];
else
TmpArray[TmpPos++]=A[Rpos++];
while(Lpos<=LeftEnd)/*Copyrestoffirsthalf*/
TmpArray[TmpPos++]=A[Lpos++];
while(Rpos<=RightEnd)/*Copyrestofsecondhalf*/
TmpArray[TmpPos++]=A[Rpos++];
for(i=0;i<NumElements;i++,RightEnd--)
/*CopyTmpArrayback*/
A[RightEnd]=TmpArray[RightEnd];}3、迭代(非遞歸)歸并排序算法A0123…………n4n3n2n1…………………………排序算法-歸并排序設(shè)n=6;6個整數(shù)是:352871(1)352871(2)3
5
28
17
(3)23
58
17
(4)123
5
78
352817(1)352
871(2)3
5
2
87
1
(3)3
5
2
8
7
1(3’)3
5
2
78
1(2’)23
5
178(1’)123
5
78
迭代算法示例:遞歸算法示例:3.2查找算法1、順序查找2、二分查找3、二分查找推廣-非線性方程的根問題:給定n個元素的數(shù)組a,查找某元素x是否在數(shù)組a中。如果在,返回該元素在數(shù)組中的下標(biāo),否則返回-1。順序查找——從列表的第一個數(shù)據(jù)(或叫做元素)開始,如果給定的數(shù)據(jù)和表中的數(shù)據(jù)匹配時,查找過程結(jié)束,給出這個數(shù)據(jù)所在表中的位置(下標(biāo))。3.2查找算法-順序查找int
Find(inta[],intn,intx){inti;/*n個元素存放在a[1]-a[n]中*/a[0]=x;/*“哨兵”*/
for(i=n;a[i]!=x;--i);returni;}int
Find(inta[],intn,intx){inti;
/*n個元素存放在a[0]-a[n-1]中*/
for(i=0;a[i]!=x&&i<n;++i);returni;}二分查找——也叫折半查找。比較列表處于一半(中間)位置的數(shù)據(jù)是否與要查找的數(shù)x相同,相同則結(jié)束查找,否則判斷是在前半部分還是后半部分(根據(jù)列表的排序確定的),然后繼續(xù)同樣的查找過程。
查找不成功的條件是查找區(qū)間已經(jīng)<=0。3.2查找算法-二分查找二分查找要求數(shù)據(jù)已經(jīng)排序。二分查找比順序查找快得多!3.2二分查找算法一個有點(diǎn)類似的問題--猜價格游戲:保證在較短時間內(nèi)猜出一件商品的價格(假設(shè)給定價格區(qū)間[10,1000]元,且是整數(shù))。條件:當(dāng)報(bào)出一個價格時,系統(tǒng)提示:高了、低了或正確。3.2二分查找算法二分查找算法(自然語言描述):假設(shè)數(shù)組A的當(dāng)前查找區(qū)間的下標(biāo)為[low,high],查找元素為x;
(1)若high<low,查找失敗,算法結(jié)束;否則取區(qū)間中間下標(biāo):mid=(low+high)/2;(2)若x<A[mid],x在[low,high]的左半?yún)^(qū),則調(diào)整新區(qū)間邊界:low不變,high=mid-1,轉(zhuǎn)(1);(3)若x>A[mid],x在[low,high]的右半?yún)^(qū),則調(diào)整新區(qū)間邊界:low=mid+1,high不變,轉(zhuǎn)(1);(4)若x==A[mid],則找到,算法結(jié)束。int
BiSearch(intx,intA[],intn){/*n個元素存放在A[1]—A[n]*/
int
low,high,mid;low=1;high=n;while(low<=high){mid=(low+high)/2;if(x<A[mid])high=mid-1;/*x在左半?yún)^(qū)*/elseif(x>A[mid])low=mid+1;/*x在右半?yún)^(qū)*/elsebreak;/*找到!*/}if(low<=high)returnmid;elsereturn0;}
3.2二分查找程序3.2二分查找推廣-非線性方程求根設(shè)有非線性方程:
f(x)=0其中f(x)在[a,b]區(qū)間內(nèi)連續(xù)且f(a)f(b)<0。因而f(x)在[a,b]區(qū)間內(nèi)至少有一個實(shí)根x0,即:f(x0)=0。寫一個程序求f(x)在[a,b]區(qū)間內(nèi)的一個近似實(shí)根。結(jié)束條件:|f(x)|<ε
或b-a<ε二分法求非線性方程的根二分法求根(自然語言描述):假設(shè)f(x)在[a,b]內(nèi)連續(xù),且f(a)f(b)<0,給定誤差ε;
(1)若b-a<ε,返回x0=(a+b)/2作為近似根,算法結(jié)束;否則取區(qū)間中點(diǎn)m=(a+b)/2;若f(m)=0,返回x0=m,算法結(jié)束;(2)若f(a)f(m)>0,在[m,b]內(nèi)必有根,則調(diào)整新區(qū)間邊界:b不變,a=m,轉(zhuǎn)(1);(3)若f(a)f(m)<0,在[a,m]內(nèi)必有根,則調(diào)整新區(qū)間邊界:a不變,b=m,轉(zhuǎn)(1);double
BiRoot(doublex,double
a,doubleb,doubleeps){/*求值函數(shù)doublef(doublex)需要另外定義*/ doublemid,fm,fa=f(a),fb=f(b);
if(fa==0.)returna;if(fb==0.)returnb;
if(fa*fb>0.){FatalError(“Fail”);return0.;}while(b-a>eps){mid=(b+a)/2;fm=f(mid);if(fm)==0.)returnmid;/*找到一個根*/elseif(fm*fa>0.){a=m;fa=fm;}/*留右半?yún)^(qū)*/else{b=m;fb=fm;}/*留左半?yún)^(qū)*/}}
3.2二分法求根3.3常用算法舉例例1:輸入n(2≤n≤5,程序不需要對此范圍進(jìn)行判斷),再輸入n個整數(shù)保存到數(shù)組a中,通過循環(huán)查找n個數(shù)中是否有重復(fù)的數(shù),如果有則輸出Yes,否則輸出No。
要求在循環(huán)過程中,任何兩個數(shù)的比較次數(shù)不得超過1次(比如對a[0]與a[1]比較后接下去又對a[1]與a[0]比較是不符合要求的),并且要求一旦找到有數(shù)重復(fù)則立即結(jié)束循環(huán)。
--
08年夏考題
#include<stdio.h> voidmain() {inta[5],i,j,n;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<=n-2;i++){ for((1);j<=n-1;j++){
if(a[i]==a[j])(2); } if((3))
break; } if((4))
puts("No"); else
puts("Yes");
}j=i+1breakj<=n-1i==n-1或i>=n-1或i>n-23.3常用算法舉例例2:函數(shù)f(A,…,x)有三個參數(shù),它們分別是已排序(升序)的數(shù)組A、整數(shù)n(A的當(dāng)前元素個數(shù))以及x(要插入到A中的整數(shù))。函數(shù)f(…)的功能是把x插入A中,而A仍然保持升序,但n增加了1。例如,A的原來5個元素是(2,4,6,8,10),n=5,x=1,程序運(yùn)行結(jié)束后的輸出是1#2#4#6#8#10#。請完成下面程序。
--06年考題
#include<stdio.h>voidfintA[],int*n,intx){inti;i=__(1)__;while((i>0)&&(x<A[i-1])){__(2)__; i--;}
A[i]=x;(*n)++;}voidmain(){
inti,A[10]={2,4,6,8,10},n=5,x=1;f(______(3)_______);
for(i=0;i<n;i++)
printf("%d#",A[i]);}*nA[i]=A[i-1];A,&n,x3.3常用算法舉例例3:數(shù)組元素循環(huán)后移問題一個數(shù)組中存有n(1<=n<=100)個整數(shù),在不允許使用另外數(shù)組的前提下,將每個數(shù)順序向后移m(m>=0)個位置(最后m個數(shù)循環(huán)移至最前面的m個數(shù))。輸入n、m及n個整數(shù),輸出循環(huán)后移m位以后的n個整數(shù)。輸入:62123456輸出:561234
數(shù)組元素循環(huán)后移問題(續(xù))1.問題分析輸入的n個整數(shù)可以放在一個一維數(shù)組中,循環(huán)右移一位的操作重復(fù)進(jìn)行m次即可。這種做法的數(shù)據(jù)移動次數(shù)大約是m(n+1)次。2.要點(diǎn)A)“循環(huán)右移一位的操作重復(fù)進(jìn)行m次”,B)m可以處理成小于n的數(shù),以減少工作量。當(dāng)m>n時,可以用m%n代替m,效果相同。但移動次數(shù)大約是(m%n)*(n+1)次。
#include<stdio.h>voidshift(intarray[],intn){
inti,array_end;
array_end=array[n-1];
for(i=n-1;i>0;i--)/*n個元素循環(huán)位移1位*/
array[i]=array[i-1];
array[0]=array_end;}voidmain(){intnumber[100],n,m,i;……/*輸入*/m%=n;/*當(dāng)m大于等于n時轉(zhuǎn)化成等價的小于n的數(shù)*/for(i=0;i<m;i++)
shift(number,n);/*n個元素循環(huán)位移1位*/……
/*輸出*/}數(shù)組元素循環(huán)后移問題(續(xù))思考1:如果修改題目要求,允許使用另外一個大小為m(假設(shè)n>m>0)數(shù)組,則如何提高程序效率?
012345234501思考2:不改變題目的任何限定(即不允許使用另外數(shù)組),能否設(shè)計(jì)一種移動次數(shù)不超過(n+gc)的方法?[gc是最大公約數(shù)]
例:n=6,m=4gc=2趟每趟移動n/gc=3個數(shù)0tmp:240voidshift_m(intarray[
],intn,intm){
inti,tmp[M];
/*M是>=m的常數(shù)*/
for(i=n-1;i>=n-m;i--)/*復(fù)制保留最后m個元素*/
tmp[i-n+m
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年版加工承攬合同具體內(nèi)容3篇
- 蔬菜溫室大棚長期租賃合同
- 2024至2030年中國車牌自動貼膜機(jī)行業(yè)投資前景及策略咨詢研究報(bào)告
- 2024至2030年中國圓形彈簧線盒行業(yè)投資前景及策略咨詢研究報(bào)告
- 2024年度商場商城物業(yè)管理智能化改造合作協(xié)議3篇
- 2024年汽車租賃違約訴訟文書3篇
- 2024年國際物流節(jié)點(diǎn)建設(shè)與運(yùn)營合同2篇
- 2021小學(xué)第十八屆推普周活動方案范文
- 2024年度財(cái)務(wù)顧問與資本運(yùn)作公司合作合同
- 2024至2030年配料調(diào)速皮帶秤項(xiàng)目投資價值分析報(bào)告
- 2024人教版五年級上冊數(shù)學(xué)期末口算題訓(xùn)練
- 2024外研版初中英語單詞表匯總(七-九年級)中考復(fù)習(xí)必背
- 安徽省合肥市包河區(qū)2023-2024學(xué)年三年級上學(xué)期期末英語試卷
- 勞動爭議調(diào)解仲裁法
- 城鎮(zhèn)歷史與遺產(chǎn)保護(hù)智慧樹知到期末考試答案2024年
- 【培訓(xùn)課件】醫(yī)療機(jī)構(gòu)從業(yè)人員行為規(guī)范
- 車間生產(chǎn)中的質(zhì)量問題與質(zhì)量改進(jìn)
- 危巖治理施工方案
- 同等學(xué)力申碩-同等學(xué)力(社會學(xué))筆試(2018-2023年)真題摘選含答案
- 疾病健康宣教的課件
- 部隊(duì)心肺復(fù)蘇
評論
0/150
提交評論