第一篇:數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)(矩陣的運(yùn)算)
數(shù) 據(jù) 結(jié) 構(gòu)
課程設(shè)計(jì)報(bào)告
題 目: 專 業(yè): 班 級(jí): 學(xué) 號(hào): 姓 名: 指導(dǎo)老師: 時(shí) 間:
一、課程設(shè)計(jì)題目及所涉及知識(shí)點(diǎn)
設(shè)計(jì)題目是“矩陣的運(yùn)算”,所涉及的知識(shí)點(diǎn)主要是:
1、數(shù)據(jù)結(jié)構(gòu)中的對(duì)于結(jié)構(gòu)體的定義,用typedef struct來實(shí)現(xiàn),根據(jù)所設(shè)計(jì)的問題在結(jié)構(gòu)體里面定義數(shù)據(jù)類型及其變量,用define定義數(shù)組的大小,然后利用typedef 來實(shí)現(xiàn)對(duì)于變量的未知類型確定正確的類型。
2、利用數(shù)組的形式來儲(chǔ)存數(shù)據(jù),在實(shí)現(xiàn)不同操作過程中,有的用一維結(jié)構(gòu)體數(shù)組(三元組順序表)來存儲(chǔ),有的用二維數(shù)組來儲(chǔ)存。
3、轉(zhuǎn)置的過程中利用的是快速轉(zhuǎn)置的方法,附設(shè)了num和cpot兩個(gè)輔助變量。
4、矩陣的加法、減法、乘法、逆運(yùn)算的基本算法方式。
5、通過調(diào)用每個(gè)函數(shù),來實(shí)現(xiàn)每個(gè)算法的功能。
二、課程設(shè)計(jì)思路及算法描述
設(shè)計(jì)思路:
1、首先是對(duì)于轉(zhuǎn)置的考慮,要運(yùn)用快速轉(zhuǎn)置的方法實(shí)現(xiàn),必須用三元組順序表來儲(chǔ)存數(shù)據(jù),所以在第一個(gè)結(jié)構(gòu)體中存在int類型的行數(shù)(mu)列數(shù)(nu)以及非零元素的個(gè)數(shù)(tu);然后第二個(gè)結(jié)構(gòu)體中分別有非零元素的行下標(biāo)(i)、列下標(biāo)(j)和元素?cái)?shù)值(e),最后在第一個(gè)結(jié)構(gòu)體中實(shí)現(xiàn)對(duì)第二個(gè)結(jié)構(gòu)體成為數(shù)組結(jié)構(gòu)體類型。
2、對(duì)于其余加法、減法、乘法和逆運(yùn)算則是運(yùn)用另一個(gè)結(jié)構(gòu)體來實(shí)現(xiàn),里面只有矩陣的行數(shù)、列數(shù)和一個(gè)二維數(shù)組(用float來定義類型)。
3、在main函數(shù)里面,來實(shí)現(xiàn)對(duì)于數(shù)據(jù)的輸入操作,利用if語句進(jìn)行選擇來執(zhí)行操作,利用do……while語句來實(shí)現(xiàn)功能的循環(huán)操作。
4、分五個(gè)函數(shù)調(diào)用分別來實(shí)現(xiàn)轉(zhuǎn)置、加法、乘法、和逆運(yùn)算,每個(gè)里面都有最終輸出結(jié)果的方式。
算法1:矩陣的轉(zhuǎn)置
輸入:mu中存放矩陣的行數(shù),tu存放矩陣的列數(shù),i接收行下標(biāo)的數(shù)值,j接收列下標(biāo)的數(shù)值,e來存儲(chǔ)數(shù)據(jù)。輸出:轉(zhuǎn)置后的新矩陣。
輸入兩行兩列數(shù)據(jù),在第二行第一列中有個(gè)數(shù)據(jù)為12,其余都為0,則輸出的結(jié)果為第一行第二列數(shù)據(jù)為12,其余為0。
算法2:矩陣的加法運(yùn)算 輸入:i中存放矩陣的行數(shù),j中存放矩陣的列數(shù),二維數(shù)組b中存放每個(gè)數(shù)據(jù)。
輸出:矩陣加完后的另一個(gè)新矩陣。
輸入兩個(gè)兩行三列的矩陣,在第一個(gè)矩陣?yán)锩娴谝恍械谝涣杏袀€(gè)數(shù)據(jù)20,其余為0,在第二個(gè)矩陣?yán)锩娴谝恍械诙兄杏袀€(gè)數(shù)據(jù)30,其余為0,則輸出的結(jié)果為一個(gè)兩行三列的矩陣,其中第一行第一列數(shù)據(jù)為20,第一行第二列數(shù)據(jù)為30,其余為0。
算法3:矩陣的減法運(yùn)算
輸入:i中存放矩陣的行數(shù),j中存放矩陣的列數(shù),二維數(shù)組b中存放每個(gè)數(shù)據(jù)。
輸出:矩陣相減后的另一個(gè)新矩陣。
輸入兩個(gè)兩行三列的矩陣,在第一個(gè)矩陣?yán)锩娴谝恍械谝涣杏袀€(gè)數(shù)據(jù)20,其余為0,在第二個(gè)矩陣?yán)锩娴谝恍械谝涣兄杏袀€(gè)數(shù)據(jù)30,其余為0,則輸出的結(jié)果為一個(gè)兩行三列的矩陣,其中第一行第一列數(shù)據(jù)為-10,其余為0。
算法4:矩陣的乘法運(yùn)算
輸入:i中存放矩陣的行數(shù),j中存放矩陣的列數(shù),二維數(shù)組b中存放每個(gè)數(shù)據(jù)。
輸出:矩陣加完后的另一個(gè)新矩陣。
輸入兩行兩列的矩陣,第一個(gè)矩陣?yán)锩娴谝恍械谝涣杏袀€(gè)數(shù)據(jù)2第二列有個(gè)數(shù)據(jù)3,其余為0,在第二個(gè)矩陣?yán)锩娴谝恍械谝涣杏袀€(gè)數(shù)據(jù)2第二列中有個(gè)數(shù)據(jù)3,其余為0,則輸出的結(jié)果為一個(gè)兩行兩列的矩陣,其中第一行第一列數(shù)據(jù)為4,第二列為6,第一行第二列數(shù)據(jù)為30,其余為0。
算法五:矩陣的逆運(yùn)算
輸入:i中存放矩陣的行數(shù),j中存放矩陣的列數(shù),二維數(shù)組b中存放每個(gè)數(shù)據(jù)。
輸出:矩陣進(jìn)行逆運(yùn)算完后的另一個(gè)新矩陣。
輸入三行三列的矩陣,第一個(gè)矩陣?yán)锩娴谝恍械谝涣杏袀€(gè)數(shù)據(jù)3個(gè)數(shù)據(jù)分別為1,2,3;第二行的數(shù)據(jù)分別為2,2,1;第三行的暑假分別為3,4,3;則輸出的結(jié)果為三行三列矩陣,其中第一行的數(shù)據(jù)為1,3,-2;第二行的數(shù)據(jù)分別為-1.5,-3,2.5;
第三行的數(shù)據(jù)分別為1,1,-1。
三、課程設(shè)計(jì)中遇到的難點(diǎn)及解決辦法
1、在轉(zhuǎn)置的過程中,要求把轉(zhuǎn)置后的矩陣輸出出來,因?yàn)橛玫氖侨M順序表的存儲(chǔ)形式,所以不知道怎么去實(shí)現(xiàn),然后通過進(jìn)一步思考,運(yùn)用先把一個(gè)矩陣存入零元素,然后在對(duì)其進(jìn)行更改,最后完成了此項(xiàng)的工作。
2、就是對(duì)于矩陣的乘法運(yùn)算和逆運(yùn)算,掌握的不夠熟練,先是通過書籍對(duì)于矩陣的乘 法和逆運(yùn)算得到更深的了解,然后通過一步步寫程序最后實(shí)現(xiàn)了矩陣的乘法運(yùn)算和逆運(yùn)算。
四、總結(jié)
通過此次課程設(shè)計(jì),讓我對(duì)于編程有了更深的認(rèn)識(shí),老師的精心指導(dǎo)讓我學(xué)會(huì)到了很多,不僅僅是代碼,最主要的讓我的思維開闊了很多,在這個(gè)過程中,通過不斷的嘗試,不斷的修改,最終克服了困難,完成了自己的任務(wù),心里有種無比的喜悅,但同時(shí)又感覺到了自己的知識(shí)面的狹隘,還有好多知識(shí)的海洋還沒有暢游,等待自己將是一回更大的考驗(yàn)。
對(duì)于現(xiàn)在的自己,對(duì)學(xué)習(xí)程序還是有很大的興趣,它讓我體驗(yàn)到了很多的快樂,我要進(jìn)步跟進(jìn)現(xiàn)在的課程,努力去發(fā)展自己,按照老師說的最主要的是具有了編程的思想,則具有了編程的能力,我想我可以成功完成自己的目標(biāo)。
五、附錄—主要源程序代碼及運(yùn)行結(jié)果
1、主要源程序代碼: # include
elemtype e;}triple;typedef struct { triple data[maxsize+1];//非零元三元組,data[0]未用 int mu,nu,tu;//矩陣的行數(shù)、列數(shù)和非零元個(gè)數(shù) }sqlist;void zhuanzhi(sqlist s1,tsmatrix &l2)//矩陣的轉(zhuǎn)置
{ sqlist s2;int col,t9,p,q,a1,b1;int num[100],copt[100];s2.mu=s1.mu;s2.nu=s1.nu;s2.tu=s1.tu;if(s2.tu>0){ for(col=1;col<=s1.nu;++col)num[col]=0;for(t9=1;t9<=s1.tu;++t9)
++num[s1.data[t9].j];//求s1中每一列含非零元個(gè)數(shù)
copt[1]=1;//求第col列中第一個(gè)非零元在s2.data中序號(hào)
for(col=2;col<=s1.nu;++col)copt[col]=copt[col-1]+num[col-1];for(p=1;p<=s1.tu;++p)
{ col=s1.data[p].j;
q=copt[col];
s2.data[q].i=s1.data[q].j;s2.data[q].j=s1.data[q].i;s2.data[q].e=s1.data[q].e;++copt[col];
l2.b[s2.data[q].i][s2.data[q].j]=s2.data[q].e;} printf(“轉(zhuǎn)置后的數(shù)據(jù)是:n”);printf(“**************************************n”);for(a1=1;a1<=s1.nu;a1++){ for(b1=1;b1<=s1.mu;b1++){printf(“%10.3f”,l2.b[a1][b1]);
printf(“t”);} printf(“n”);} printf(“************************************”);printf(“n”);} } void jiafa(tsmatrix l4, tsmatrix l5)//矩陣的加法 {tsmatrix l6;for(int t=0;t for(j=0;j<(2*s.i);j++) { if(j else if(j==s.i+i)s1.b[i][j]=1.0; else s1.b[i][j]=0.0; } for(i=0;i { for(k=0;k {if(k!=i) { t=s1.b[k][i]/s1.b[i][i]; for(j=0;j<(2*s.i);j++) { x=s1.b[i][j]*t; s1.b[k][j]=s1.b[k][j]-x; } } }} for(i=0;i s1.b[i][j]=s1.b[i][j]/t;} float y=1.0;for(i=0;i printf(“對(duì)不起,您輸入的矩陣沒有逆矩陣”); else { for(i=0;i for(j=0;j { for(j=0;j printf(“%10.3f”,s.b[i][j]); printf(“n”);}}} void main(){ tsmatrix l,l1,l3;sqlist s;int m,n,m1,n1,n4,n5,t,t1,t2,t3,t4,t5,t6,t7,t8;do{ printf(“請(qǐng)輸入你要進(jìn)行的操作:n”); printf(“******************************n”); printf(“矩陣轉(zhuǎn)置運(yùn)算請(qǐng)按1n矩陣的加法運(yùn)算請(qǐng)按2n矩陣的乘法運(yùn)算請(qǐng)按3n矩陣的減法運(yùn)算請(qǐng)按4n矩陣的逆運(yùn)算請(qǐng)按5n結(jié)束請(qǐng)按0:n”);printf(“******************************n”);scanf(“%d”,&m1);if(m1==1){ printf(“您選擇進(jìn)行的操作是矩陣的轉(zhuǎn)置運(yùn)算nn”); printf(“請(qǐng)輸入你要轉(zhuǎn)置矩陣的行數(shù)、列數(shù)和非零元的個(gè)數(shù)n”);scanf(“%d”,&t1); scanf(“%d”,&t2);scanf(“%d”,&t3);s.mu=t1;s.nu=t2;s.tu=t3;printf(“請(qǐng)輸入你要轉(zhuǎn)置矩陣非零元的行下標(biāo)、列下標(biāo)(從[1][1]開始由左至右由上到下)及其數(shù)據(jù)(按行逐個(gè)輸入)n”);for(t4=1;t4<=s.tu;t4++){scanf(“%d”,&t5);scanf(“%d”,&t6); s.data[t4].i=t5;s.data[t4].j=t6; scanf(“%f”,&s.data[t4].e);} for(t7=1;t7<=s.nu;t7++){ for(t8=1;t8<=s.mu;t8++)l1.b[t7][t8]=0.0;} zhuanzhi(s,l1);} if(m1==2){ printf(“您選擇進(jìn)行的操作是矩陣的加法運(yùn)算nn”);printf(“請(qǐng)輸入矩陣的行數(shù)和列數(shù):n”);scanf(“%d”,&n);scanf(“%d”,&m);l.i=n;l.j=m;l3.i=n;l3.j=m;printf(“******************************n”);printf(“請(qǐng)輸入第一個(gè)%d行%d列的矩陣n”,l.i,l.j);{ for(t=0;t if(m1==5){ printf(“您選擇進(jìn)行的操作是矩陣的逆運(yùn)算nn”);printf(“請(qǐng)輸入矩陣的維數(shù)(即行和列相等的矩陣):n”);scanf(“%d”,&n);l.i=n;l.j=n;printf(“******************************n”);printf(“請(qǐng)輸入%d行%d列的矩陣n”,l.i,l.j);{ for(t=0;t 2、運(yùn)行結(jié)果(如下圖): (1)、執(zhí)行的首界面: (2)、矩陣的轉(zhuǎn)置運(yùn)算: (3)、矩陣的加法運(yùn)算: (4)、矩陣的減法運(yùn)算: (5)、矩陣的乘法 (6)、矩陣的逆運(yùn)算: (7)、矩陣可以循環(huán)運(yùn)算: 六、指導(dǎo)老師評(píng)語及成績(jī) 數(shù)據(jù)結(jié)構(gòu) 課程設(shè)計(jì)報(bào)告 設(shè)計(jì)題目: n維矩陣乘法:A B-1 專 業(yè) 計(jì)算機(jī)科學(xué)與技術(shù) 班 級(jí) 計(jì)本 學(xué) 生 學(xué) 號(hào) 指導(dǎo)教師 起止時(shí)間 2007.X.3-2007.X.11 學(xué)年第I 學(xué)期 一、具體任務(wù) 功能: 設(shè)計(jì)一個(gè)矩陣相乘的程序,首先從鍵盤輸入兩個(gè)矩陣a,b的內(nèi)容,并輸出兩個(gè)矩陣,輸出ab-1結(jié)果。 分步實(shí)施: 1.初步完成總體設(shè)計(jì),搭好框架,確定人機(jī)對(duì)話的界面,確定函數(shù)個(gè)數(shù); 2.完成最低要求:建立一個(gè)文件,可完成2維矩陣的情況; 3.進(jìn)一步要求:通過鍵盤輸入維數(shù)n。有興趣的同學(xué)可以自己擴(kuò)充系統(tǒng)功能。 要求: 1.界面友好,函數(shù)功能要?jiǎng)澐趾?/p> 2.總體設(shè)計(jì)應(yīng)畫一流程圖 3.程序要加必要的注釋 4.要提供程序測(cè)試方案 5.程序一定要經(jīng)得起測(cè)試,寧可功能少一些,也要能運(yùn)行起來,不能運(yùn)行的程序是沒有價(jià)值的。 二、軟件環(huán)境 Microsoft Visual C++ 6.0 三、問題的需求分析 程序以二維數(shù)組作為矩陣的存儲(chǔ)結(jié)構(gòu),通過鍵盤輸入矩陣維數(shù)n,動(dòng)態(tài)分配內(nèi)存空間,創(chuàng)建n維矩陣。矩陣建立后再通過鍵盤輸入矩陣的各個(gè)元素值;也可以通過文件讀入矩陣的各項(xiàng)數(shù)據(jù)(維數(shù)及各元素值)。 當(dāng)要對(duì)矩陣作進(jìn)一步操作(A*B或A*B^(-1))時(shí),先判斷內(nèi)存中是否已經(jīng)有相關(guān)的數(shù)據(jù)存在,若還未有數(shù)據(jù)存在則提示用戶先輸入相關(guān)數(shù)據(jù)。 當(dāng)要對(duì)矩陣進(jìn)行求逆時(shí),先利用矩陣可逆的充要條件:|A| != 0 判斷矩陣是否可逆,若矩陣的行列式 |A| = = 0 則提示該矩陣為不可逆的;若 |A| !=0 則求其逆矩陣,并在終端顯示其逆矩陣。 四、算法設(shè)計(jì)思想及流程圖 1.抽象數(shù)據(jù)類型 ADT MatrixMulti{ 數(shù)據(jù)對(duì)象:D = {a(I,j)|i = 1,2,3,…,n;j = 1,2,…,n;a(i,j)∈ElemSet,n為矩陣維數(shù)} 數(shù)據(jù)關(guān)系: R = {Row,Col} Row = {| <= i <= n,1 <= j <= n-1} Col = {| <= i <= n-1,1 <= j <= n} 基本操作: Swap(&a,&b); 初始條件:記錄a,b已存在。 操作結(jié)果:交換記錄a,b的值。 CreateMatrix(n); 操作結(jié)果:創(chuàng)建n維矩陣,返回該矩陣。 Input(&M); 初始條件:矩陣M已存在。 操作結(jié)果:從終端讀入矩陣M的各個(gè)元素值。 Print(&M) 初始條件:矩陣M已存在。 操作結(jié)果:在終端顯示矩陣M的各個(gè)元素值。 ReadFromFile(); 操作結(jié)果:從文件讀入矩陣的相關(guān)數(shù)據(jù)。 Menu_Select(); 操作結(jié)果:返回菜單選項(xiàng)。 MultMatrix(&M1,&M2,&R); 初始條件:矩陣M1,M2,R已存在。 操作結(jié)果:矩陣M1,M2作乘法運(yùn)算,結(jié)果放在R中。 DinV(&M,&V); 初始條件:矩陣M,V已存在。 操作結(jié)果:求矩陣M的逆矩陣,結(jié)果放入矩陣V中。 MatrixDeterm(&M,n); 初始條件:矩陣M已存在。 操作結(jié)果:求矩陣M的行列式的值。 } ADT MatrixMulti 2.矩陣求逆算法設(shè)計(jì)思想 算法采用高斯-約旦法(全選主元)求逆,主要思想如下: 首先,對(duì)于k從0到n-1作如下幾步: ① 從第k行、第k列開始的右下角子陣中選取絕對(duì)值最大的元素,并記住此元素所在的行號(hào)與列號(hào),再通過行交換和列交換將它交換到主元素位置上。這一步稱為全選主元。 ② 主元求倒:M(k,k) = / M(k,k) ③ M(k,j) = M(k,j) * M(k,k);j = 0,1,…,n-1;j != k ④ M(i,j) = M(i,j) – M(i,k) * M(k,j);i,j = 0,1,…,n-1;i,j!=k ⑤ M(i,k) = M(i,k) * M(k,k),i = 0,1…,n-1;i != k 最后,根據(jù)在全選主元過程中所記錄的行、列交換的信息進(jìn)行恢復(fù),恢復(fù)原則如下: 在全選主元過程中,先交換的行(列)后進(jìn)行恢復(fù);原來的行(列)交換用列(行)交換來恢復(fù)。 3.矩陣行列式求值運(yùn)算算法設(shè)計(jì)思想 利用行列式的性質(zhì):行列式等于它的任一行(列)各元素與其對(duì)應(yīng)的代數(shù)余子式乘積,即 D = ∑a(i,k)*A(i,k) ; k = 1,2,…,n; D = ∑a(k,j)*A(k,j) ; k = 1,2,…,n; 再利用函數(shù)的遞歸調(diào)用法實(shí)現(xiàn)求其值。 4.各函數(shù)間的調(diào)用關(guān)系 Main() ReadFromFile() DinV() Swap () Print() Menu_Select() MatrixDeterm() CreateMatrix() MultMatrix() Input() 5.流程圖 否 否 是 否 是 是 否 是 否 否 是 開始 switch(Menu_Select()) case 1: case 3: case 2: n 0 ? 是 輸入矩陣維數(shù)n 輸入矩陣A,B 輸出矩陣維數(shù)n system(“pause”); 通過鍵盤輸入需對(duì)哪個(gè)矩陣求逆,求出相應(yīng)該的逆陣,并顯示求得的逆陣system(“pause”);若矩陣不可逆則返回主菜單 case 4: R=A*B并顯示矩陣R system(“pause”); case 5: 是 否 是 R=A*B^(-1)顯示矩陣R system(“pause”);若B不可逆,則返回主菜單 case 6: 從指定文件中讀入矩陣數(shù)據(jù) case 0: exit(0); 結(jié)果 否 五、源代碼 #include #include #include #include #include #include #define YES #define NO 0 typedef float ElemType; ElemType **A; //矩陣A ElemType **B; //矩陣B ElemType **R; //矩陣R,用于存放運(yùn)算結(jié)果 ElemType **V; //矩陣V,存放逆矩陣 int n=0; //矩陣維數(shù) int flag=-1; //標(biāo)記 void swap(ElemType *a,ElemType *b) //交換記錄a,b的值 { ElemType c; c=*a; *a=*b; *b=c; } ElemType **CreateMatrix(int n) //創(chuàng)建n維矩陣,返回該矩陣 { int i,j; ElemType **M; M = (ElemType **)malloc(sizeof(ElemType *)*n); if(M == NULL) exit(1); for(i=0;i { *(M+i) = (ElemType *)malloc(sizeof(ElemType)*n); for(j=0;j *(*(M+i)+j) = 0; } return M; } ElemType MatrixDeterm(ElemType **M,int n) /*遞歸法求n維矩陣行列式的值,返回運(yùn)算結(jié)果*/ { int i,j,k,l,s; ElemType **T1; ElemType **T2; T1=CreateMatrix(n); T2=CreateMatrix(n); ElemType u; ElemType value=0; //運(yùn)算結(jié)果 for(i=0;i { for(j=0;j { T1[i][j]=M[i][j]; T2[i][j]=M[i][j]; } } if(n==2) //若為2維矩陣,則直接運(yùn)算并返回運(yùn)算結(jié)果 { value=T2[0][0]*T2[1][1]-T2[0][1]*T2[1][0]; return value; } else { for(j=0;j //將矩陣的行列式以第一行展開 { u=T1[0][j]; for(i=1,l=0;i //求矩陣行列式的余子式M(0,j) { for(k=0,s=0;k { if(k==j) continue; else { T2[l][s]=T1[i][k]; s++; } } l++; } value=value+u*((int)pow(-1,j))*MatrixDeterm(T2,n-1); /*行列式等于某一行的各個(gè)元素與其代數(shù)余子式的乘積之和*/ } return value; } } int DinV(ElemType **M,ElemType **V) /*全選主元法求矩陣M的逆矩陣,結(jié)果存入矩陣V中*/ { int i,j,k; ElemType d; ElemType u; int *JS,*IS; JS=(int *)malloc(sizeof(int)*n); IS=(int *)malloc(sizeof(int)*n); u=MatrixDeterm(M,n); //返回矩陣A的行列式值 if(u==0) return -1; for(i=0;i for(j=0;j V[i][j]=M[i][j]; for(k=0;k { d=0; for(i=k;i //找出矩陣M從M[k][k]開始絕對(duì)值最大的元素 { for(j=k;j { if(fabs(V[i][j])>d) { d=fabs(V[i][j]); //d記錄絕對(duì)值最大的元素的值 /*把絕對(duì)值最大的元素在數(shù)組中的行、列坐標(biāo)分別存入IS[K],JS[K]*/ IS[k]=i; JS[k]=j; } } } if(d+1.0 == 1.0) return 0; //所有元素都為0 if(IS[k] != k) /*若絕對(duì)值最大的元素不在第k行,則將矩陣IS[K]行的元素與k行的元素相交換*/ for(j=0;j swap(&V[k][j],&V[IS[k]][j]); if(JS[k]!=k) /*若絕對(duì)值最大的元素不在第k列,則將矩陣JS[K]列的元素與k列的元素相交換*/ for(i=0;i swap(&V[i][k],&V[i][JS[k]]); V[k][k]=1/V[k][k]; //絕對(duì)值最大的元素求倒 for(j=0;j /*矩陣M第k行除元素M[k][k]本身外都乘以M[k][k]*/ if(j!=k) V[k][j]=V[k][j]*V[k][k]; for(i=0;i /*矩陣除第k行的所有元素與第k列的所有元素外,都拿本身減去M[i][k]*M[k][j],其中i,j為元素本身在矩陣的位置坐標(biāo)*/ if(i!=k) for(j=0;j if(j!=k) V[i][j]=V[i][j]-V[i][k]*V[k][j]; for(i=0;i /*矩陣M第k列除元素M[k][k]本身外都乘以-M[k][k]*/ if(i!=k) V[i][k]=-V[i][k]*V[k][k]; } for(k=n-1;k>=0;k--) /*根據(jù)上面記錄的行IS[k],列JS[k]信息恢復(fù)元素*/ { for(j=0;j if(JS[k]!=k) swap(&V[k][j],&V[JS[k]][j]); for(i=0;i if(IS[k]!=k) swap(&V[i][k],&V[i][IS[k]]); } free(IS); free(JS); return 0; } void MultMatrix(ElemType **M1,ElemType **M2,ElemType **R) /*矩陣M1乘M2 結(jié)果存入矩陣R*/ { int i,j,k; for(i=0;i { for(j=0;j { R[i][j]=0; } } for(i=0;i { for(j=0;j { for(k=0;k { R[i][j]=R[i][j]+M1[i][k]*M2[k][j]; } } } } void Input(ElemType **M) //輸入矩陣M的各個(gè)元素值 { int i,j; char str[10]; char c='A'; if(flag==1) c='B'; system(“cls“); printf(“\n\n輸入矩陣%c(%d*%d)\n“,c,n,n); for(i=0;i { for(j=0;j { scanf(“%f“,*(M+i)+j); } } flag=1; gets(str); //吸收多余的字符 } void Print(ElemType **M) //顯示矩陣M的各個(gè)元素值 { int i,j; printf(“\t“); for(i=0;i { for(j=0;j { printf(“ %.3f“,M[i][j]); } puts(““); printf(“\t\t“); } } int Menu_Select() { char c; do{ system(“cls“); puts(“\t\t*************n維矩陣乘法器*************“); puts(“\t\t| 1.通過鍵盤輸入各項(xiàng)數(shù)據(jù) |“); puts(“\t\t| 2.顯示矩陣A,B |“); puts(“\t\t| 3.矩陣求逆,并顯示逆矩陣 |“); puts(“\t\t| 4.求矩陣運(yùn)算A*B,并顯示運(yùn)算結(jié)果 |“); puts(“\t\t| 5.求矩陣運(yùn)算A*B^(-1),并顯示運(yùn)算結(jié)果|“); puts(“\t\t| 6.從文件讀入矩陣A,B與維數(shù)n |“); puts(“\t\t| 0.退出 |“); puts(“\t\t***************************************“); printf(“\t\t請(qǐng)選擇(0-6):“); c=getchar(); }while(c<'0'||c>'6'); return (c-'0'); } void ReadFromFile() //從指定文件讀入矩陣的維數(shù)及矩陣各元素的值 { int i,j; FILE *fp; if((fp=fopen(“tx.txt“,“r“))==NULL) { puts(“無法打開文件!!“); system(“pause“); exit(0); } fscanf(fp,“%d“,&n); //讀入矩陣維數(shù) A=CreateMatrix(n); //創(chuàng)建矩陣A B V R B=CreateMatrix(n); V=CreateMatrix(n); R=CreateMatrix(n); for(i=0;i //讀入矩陣A { for(j=0;j { fscanf(fp,“%f“,&A[i][j]); } } for(i=0;i //讀入矩陣A { for(j=0;j { fscanf(fp,“%f“,&B[i][j]); } } puts(“\n\n讀文件成功“); fclose(fp); flag=1; } int main() { int i; char c,h; char str[10]; for(;;) { switch(Menu_Select()) { case 1: flag=-1; for(;;) { system(“cls“); printf(“\n\n\t矩陣維數(shù)n:“); scanf(“%d“,&n); gets(str); if(n>0) break; else { printf(“\n\t輸入有誤,請(qǐng)重新輸入!\n“); puts(““); system(“pause“); } } A=CreateMatrix(n); B=CreateMatrix(n); V=CreateMatrix(n); R=CreateMatrix(n); Input(A); Input(B); break; case 2: system(“cls“); if(flag==-1) { puts(“\n\n\t不存在任何矩陣數(shù)據(jù),請(qǐng)先輸入數(shù)據(jù)“); system(“pause“); break; } puts(“\n“); printf(“\tA = “); Print(A); puts(“\n“); printf(“\tB = “); Print(B); puts(““); system(“pause“); break; case 3: system(“cls“); if(flag==-1) { puts(“\n\n\t不存在任何矩陣數(shù)據(jù),請(qǐng)先輸入數(shù)據(jù)“); system(“pause“); break; } for(;;) { printf(“\n\n\t輸入需要求逆的矩陣(A/B):“); h=getchar(); c=getchar(); //h=getchar(); if(c=='A'||c=='a') { i=DinV(A,V); if(i==-1) { puts(“\n\n\t矩陣A的行列式等于0,不可逆!“); system(“pause“); break; } printf(“\tA = “); Print(A); puts(“\n“); printf(“A^(-1) = “); Print(V); puts(““); system(“pause“); break; } else if(c=='B'||c=='b') { i=DinV(B,V); if(i==-1) { puts(“\n\n\t矩陣B的行列式等于0,不可逆!“); system(“pause“); break; } printf(“\tB = “); Print(B); puts(“\n“); printf(“B^(-1) = “); Print(V); puts(““); system(“pause“); break; } else puts(“\n\n\t輸入有誤,請(qǐng)重新輸入!\n“); } break; case 4: system(“cls“); if(flag==-1) { puts(“\n\n\t不存在任何矩陣數(shù)據(jù),請(qǐng)先輸入數(shù)據(jù)“); system(“pause“); break; } MultMatrix(A,B,R); printf(“\n\n\tA*B = “); Print(R); puts(““); system(“pause“); break; case 5: system(“cls“); if(flag==-1) { puts(“\n\n\t不存在任何矩陣數(shù)據(jù),請(qǐng)先輸入數(shù)據(jù)“); system(“pause“); break; } i=DinV(B,V); if(i==-1) { puts(“\n\n\t矩陣B的行列式等于0,不可逆!“); system(“pause“); break; } MultMatrix(A,V,R); printf(“\n\nA*B^(-1) = “); Print(R); puts(““); system(“pause“); break; case 6: system(“cls“); ReadFromFile(); puts(““); system(“pause“); break; case 0: puts(“\t\t正常退出“); exit(0); break; } } return 0; } 六、運(yùn)行結(jié)果 1.主界面: 2.輸入6,回車,從文本文件tx.txt中讀入矩陣數(shù)據(jù): 3.回車,回到主菜單界面;輸入2回車,顯示從文件讀入的矩陣數(shù)據(jù): 4.回車,回到主菜單界面;輸入3回車,對(duì)指定矩陣求逆:(由于這里矩陣A是不可逆的,因此僅以矩陣B為例) 5.回車,回到主菜單界面;輸入4回車,求矩陣運(yùn)算A*B: 6.回車回到主菜單界面,輸入5回車,求A*B^(-1)的值: 7.回車回到主菜單界面,輸入0回車,退出程序;如果需要自定矩陣維數(shù)及各元素值,請(qǐng)利用主菜單里的1號(hào)功能自行輸入數(shù)據(jù),再進(jìn)行以上幾種運(yùn)算操作。 七、收獲及體會(huì) 通過這次課程設(shè)計(jì),讓我再次復(fù)習(xí)了線性代數(shù)里矩陣的相關(guān)知識(shí),比如n維矩陣的求逆、矩陣可逆的充分必要條件(|A| != 0)、矩陣與矩陣的乘法運(yùn)算、行列式求值方法等。同樣的,還讓我復(fù)習(xí)了大量C語言里有關(guān)數(shù)組的一些重要概念,比如多維數(shù)組的動(dòng)態(tài)分配問題、數(shù)組與指針的關(guān)系等。 記得在這個(gè)學(xué)期新開設(shè)的單片機(jī)基礎(chǔ)課上,吳濤老師曾多次強(qiáng)調(diào),讓我們一定要經(jīng)常鍛煉自己的編程能力,他常對(duì)我們說:“編程是思維的體操?!北M管我在這方面的能力 和實(shí)力非常得有限,也遠(yuǎn)遠(yuǎn)不及班上的其他同學(xué),但我通過這次課程設(shè)計(jì)充分體會(huì)到了這句話的精華。 電腦程序作為人體大腦思維的延伸,程序的功能也會(huì)因?yàn)榇竽X思維的不斷完善而變得更加強(qiáng)大,所以我決定今后要加強(qiáng)在這方面的鍛煉和學(xué)習(xí),以此來激勵(lì)自己不斷前進(jìn)! 八、參考文獻(xiàn) 《數(shù)據(jù)結(jié)構(gòu)(C語言版)》 嚴(yán)蔚敏,吳偉民 編著 清華大學(xué)出版社 《C語言程序設(shè)計(jì)》 洪維恩 編著 中國鐵道出版社 《C語言程序設(shè)計(jì)教程》 譚浩強(qiáng) 張基溫 唐永炎 編著 高等教育出版社 《工程數(shù)學(xué)——線性代數(shù) 第四版》 同濟(jì)大學(xué)應(yīng)用數(shù)學(xué)系 編 高等教育出版社 計(jì)本 2007-12 實(shí)驗(yàn)五 數(shù)組的運(yùn)算 實(shí)驗(yàn)?zāi)康模?/p> 掌握稀疏矩陣的壓縮存儲(chǔ)方法及主要運(yùn)算的實(shí)現(xiàn)。實(shí)驗(yàn)內(nèi)容與要求: 設(shè)計(jì)一個(gè)稀疏矩陣計(jì)算器,要求能夠:⑴輸入并建立稀疏矩陣;⑵輸出稀疏矩陣;⑶執(zhí)行兩個(gè)矩陣相加;⑷求一個(gè)矩陣的轉(zhuǎn)置矩陣。 程序代碼: #include typedef struct { int i,j; datatype v; }node;typedef struct { node data[smax]; int m,n,t; }spmatrix; void creat(spmatrix a)創(chuàng)建輸出稀疏矩陣 { int k=0; printf(“請(qǐng)輸入稀疏矩陣:n”); scanf(“%d,%d,%d”,&a.m,&a.n,&a.t); scanf(“%d,%d,%d”,&a.data[0].i,&a.data[0].j,&a.data[0].v); while(a.data[k].v!=0)以0元素作為結(jié)束標(biāo)志,因?yàn)橄∈杈仃嚥话?元素 {k++; scanf(“%d,%d,%d”,&a.data[k].i,&a.data[k].j,&a.data[k].v); } printf(“輸出的稀疏矩陣是:n”); printf(“%d,%d,%dn”,a.m,a.n,a.t); for(k=0;k printf(“%d,%d,%dn”,a.data[k].i,a.data[k].j,a.data[k].v); printf(“n”);} void transpose(spmatrix a)轉(zhuǎn)置函數(shù) { int p,q,k=0; printf(“請(qǐng)輸入稀疏矩陣:n”); scanf(“%d,%d,%d”,&a.m,&a.n,&a.t); scanf(“%d,%d,%d”,&a.data[0].i,&a.data[0].j,&a.data[0].v); while(a.data[k].v!=0) {k++; scanf(“%d,%d,%d”,&a.data[k].i,&a.data[k].j,&a.data[k].v); } for(k=0;k {p=a.data[k].i;a.data[k].i=a.data[k].j;a.data[k].j=p;} printf(“輸出轉(zhuǎn)置后的初步矩陣元素:n”); for(k=0;k printf(“%d,%d,%dn”,a.data[k].i,a.data[k].j,a.data[k].v); for(p=0;p for(k=0;k<(a.t-p);k++) {if(a.data[k].i>a.data[k+1].i ||(a.data[k].i==a.data[k+1].i && a.data[k].j>a.data[k+1].j)) {q=a.data[k].i;a.data[k].i=a.data[k+1].i;a.data[k+1].i=q; q=a.data[k].j;a.data[k].j=a.data[k+1].j;a.data[k+1].j=q; q=a.data[k].v;a.data[k].v=a.data[k+1].v;a.data[k+1].v=q; } } printf(“輸出轉(zhuǎn)置后的稀疏矩陣:n”);printf(“%d,%d,%dn”,a.n,a.m,a.t);for(k=1;k<(a.t+1);k++)此處下標(biāo)加1是根據(jù)輸出結(jié)果判定而來,不知道原因 printf(“%d,%d,%dn”,a.data[k].i,a.data[k].j,a.data[k].v);printf(“n”);} void add(spmatrix a,spmatrix b)求和函數(shù) {spmatrix c;int x=0,y=0,z=0;int p,q,r=0;printf(“請(qǐng)輸入稀疏矩陣a:n”);scanf(“%d,%d,%d”,&a.m,&a.n,&a.t);scanf(“%d,%d,%d”,&a.data[0].i,&a.data[0].j,&a.data[0].v);while(a.data[x].v!=0) {x++; scanf(“%d,%d,%d”,&a.data[x].i,&a.data[x].j,&a.data[x].v); } printf(“請(qǐng)輸入稀疏矩陣b:n”);scanf(“%d,%d,%d”,&b.m,&b.n,&b.t);scanf(“%d,%d,%d”,&b.data[0].i,&b.data[0].j,&b.data[0].v); while(a.data[y].v!=0) {y++; scanf(“%d,%d,%d”,&b.data[y].i,&b.data[y].j,&b.data[y].v); }以上為重新創(chuàng)建兩個(gè)稀疏矩陣,方便運(yùn)算 if(a.m==b.m && a.n==b.n)首先行列相等的稀疏矩陣才能相加 {for(x=0;x {c.data[z].i=a.data[x].i; c.data[z].j=a.data[x].j; c.data[z].v=a.data[x].v; z++; } for(y=0;y {c.data[z].i=b.data[y].i; c.data[z].j=b.data[y].j; c.data[z].v=b.data[y].v; z++; }兩個(gè)for循環(huán)先后把a(bǔ),b兩個(gè)稀疏矩陣元素放到一個(gè)新的稀疏矩陣c里去 printf(“輸出結(jié)合后的初步稀疏矩陣C的元素:n”);進(jìn)行一次打印 for(z=0;z<(a.t+b.t);z++)printf(“%d,%d,%dn”,c.data[z].i,c.data[z].j,c.data[z].v); for(p=0;p<(a.t+b.t);p++)冒泡排序法對(duì)新矩陣元素排序 for(z=0;z<(a.t+b.t-p);z++){if(c.data[z].i>c.data[z+1].i ||(c.data[z].i==c.data[z+1].i && c.data[z].j>c.data[z+1].j))有這幾種情況需要重新排序,首先是進(jìn)行行對(duì)比(前行大于后行進(jìn)行交換),然后當(dāng)行相等時(shí)在進(jìn)行列對(duì)比(前列大于后列時(shí)在進(jìn)行交換),其他情況均不用交換 {q=c.data[z].i;c.data[z].i=c.data[z+1].i;c.data[z+1].i=q; q=c.data[z].j;c.data[z].j=c.data[z+1].j;c.data[z+1].j=q; q=c.data[z].v;c.data[z].v=c.data[z+1].v;c.data[z+1].v=q;} } printf(“輸出排序后的稀疏矩陣C的元素:n”);進(jìn)行一次打印 for(z=1;z<(a.t+b.t+1);z++)printf(“%d,%d,%dn”,c.data[z].i,c.data[z].j,c.data[z].v); for(z=1;z<(a.t+b.t+1-r);z++)主循環(huán),保證閱讀每一個(gè)數(shù)組元素 if(c.data[z].i==c.data[z+1].i && c.data[z].j==c.data[z+1].j)在對(duì)排好序后的矩陣進(jìn)行相等行列元素的合并 {c.data[z].v=c.data[z].v+c.data[z+1].v; r++;此處是關(guān)鍵,記錄此時(shí)的步驟,如果進(jìn)行一次運(yùn)算后,那么后面的循環(huán)就要少一次,包括再回到主循環(huán)時(shí)也要少一次 for(z+1;(z+1)<(a.t+b.t+1-r);z++)小循環(huán)是讓后面的每一個(gè)數(shù)組元素向前移動(dòng)一個(gè)位置,掩蓋掉相等行列元素 {c.data[z+1].i=c.data[z+2].i; c.data[z+1].j=c.data[z+2].j; c.data[z+1].v=c.data[z+2].j; } } printf(“輸出最終結(jié)果的稀疏矩陣C:n”);printf(“%d,%d,%dn”,a.m,a.n,(a.t+b.t-r));輸出稀疏矩陣表頭時(shí)只需將行列元素交換輸出即可,元素個(gè)數(shù)輸出時(shí)要注意相等行列元素合并進(jìn)行了幾次操作,即用r記錄操作步驟的次數(shù),每進(jìn)行一次操作那么最終稀疏矩陣就少一個(gè)數(shù)組元素,同時(shí)r又是伴隨步驟增加的 for(z=1;z<(a.t+b.t+1-r);z++)原理同上 printf(“%d,%d,%dn”,c.data[z].i,c.data[z].j,c.data[z].v);} Else給出稀疏矩陣表開頭行列總和不等時(shí)則無法計(jì)算 printf(“輸入的稀疏矩陣a,b不是行列相等的矩陣。n”);} void main()主函數(shù) {spmatrix a,b;creat(a);transpose(a);add(a,b);} 心得體會(huì):程序開頭老師指點(diǎn)了一下,后面的算法以及函數(shù)全為自己長(zhǎng)時(shí)間編寫,全用一維數(shù)組包含多個(gè)數(shù)據(jù)的思想去操作,抓住主的數(shù)組元素值的變化,步步為營(yíng),一個(gè)目標(biāo)一個(gè)目標(biāo)的實(shí)現(xiàn),在操作時(shí)最好對(duì)這次操作結(jié)果做一次打印,就像程序中進(jìn)行前后元素交換的時(shí)候主數(shù)組下標(biāo)加1是為什么沒有研究透,不過通過每步打印發(fā)現(xiàn)了這個(gè)規(guī)律,要不然找死都找不出結(jié)果為何少一個(gè)元素,開頭元素為何是一串?dāng)?shù)字亂碼。 數(shù) 據(jù) 結(jié) 構(gòu) 課程設(shè)計(jì)報(bào)告 題 目: 一元多項(xiàng)式計(jì)算 專 業(yè): 信息管理與信息系統(tǒng) 班 級(jí): 2012級(jí)普本班 學(xué) 號(hào): 201201011367 姓 名: 左帥帥 指導(dǎo)老師: 郝慎學(xué) 時(shí) 間: 一、課程設(shè)計(jì)題目分析 本課程設(shè)計(jì)要求利用C語言或C++編寫,本程序?qū)崿F(xiàn)了一元多項(xiàng)式的加法、減法、乘法、除法運(yùn)算等功能。 二、設(shè)計(jì)思路 本程序采用C語言來完成課程設(shè)計(jì)。 1、首先,利用順序存儲(chǔ)結(jié)構(gòu)來構(gòu)造兩個(gè)存儲(chǔ)多項(xiàng)式A(x)和 B(x)的結(jié)構(gòu)。 2、然后把輸入,加,減,乘,除運(yùn)算分成五個(gè)主要的模塊:實(shí)現(xiàn)多項(xiàng)式輸入模塊、實(shí)現(xiàn)加法的模塊、實(shí)現(xiàn)減法的模塊、實(shí)現(xiàn)乘法的模塊、實(shí)現(xiàn)除法的模塊。 3、然后各個(gè)模塊里面還要分成若干種情況來考慮并通過函數(shù)的嵌套調(diào)用來實(shí)現(xiàn)其功能,盡量減少程序運(yùn)行時(shí)錯(cuò)誤的出現(xiàn)。 4、最后編寫main()主函數(shù)以實(shí)現(xiàn)對(duì)多項(xiàng)式輸入輸出以及加、減、乘、除,調(diào)試程序并將不足的地方加以修改。 三、設(shè)計(jì)算法分析 1、相關(guān)函數(shù)說明: (1)定義數(shù)據(jù)結(jié)構(gòu)類型為線性表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)類型變量 typedef struct Polynomial{} (2)其他功能函數(shù) 插入函數(shù)void Insert(Polyn p,Polyn h) 比較函數(shù)int compare(Polyn a,Polyn b) 建立一元多項(xiàng)式函數(shù)Polyn Create(Polyn head,int m) 求解并建立多項(xiàng)式a+b,Polyn Add(Polyn pa,Polyn pb) 求解并建立多項(xiàng)式a-b,Polyn Subtract(Polyn pa,Polyn pb)2 求解并建立多項(xiàng)式a*b,Polyn Multiply(Polyn pa,Polyn pb) 求解并建立多項(xiàng)式a/b,void Device(Polyn pa,Polyn pb) 輸出函數(shù)輸出多項(xiàng)式,void Print(Polyn P) 銷毀多項(xiàng)式函數(shù)釋放內(nèi)存,void Destroy(Polyn p) 主函數(shù),void main() 2、主程序的流程基函數(shù)調(diào)用說明(1)typedef struct Polynomial { float coef; int expn; struct Polynomial *next;} *Polyn,Polynomial; 在這個(gè)結(jié)構(gòu)體變量中coef表示每一項(xiàng)前的系數(shù),expn表示每一項(xiàng)的指數(shù),polyn為結(jié)點(diǎn)指針類型,屬于抽象數(shù)據(jù)類型通常由用戶自行定義,Polynomial表示的是結(jié)構(gòu)體中的數(shù)據(jù)對(duì)象名。 (2)當(dāng)用戶輸入兩個(gè)一元多項(xiàng)式的系數(shù)和指數(shù)后,建立鏈表,存儲(chǔ)這兩個(gè)多項(xiàng)式,主要說明如下: Polyn CreatePolyn(Polyn head,int m)建立一個(gè)頭指針為head、項(xiàng)數(shù)為m的一元多項(xiàng)式 p=head=(Polyn)malloc(sizeof(struct Polynomial));為輸入的多項(xiàng)式申請(qǐng)足夠的存儲(chǔ)空間 p=(Polyn)malloc(sizeof(struct Polynomial));建立新結(jié)點(diǎn)以接收數(shù)據(jù) Insert(p,head);調(diào)用Insert函數(shù)插入結(jié)點(diǎn) 這就建立一元多項(xiàng)式的關(guān)鍵步驟 (3)由于多項(xiàng)式的系數(shù)和指數(shù)都是隨即輸入的,所以根據(jù)要求需要對(duì)多項(xiàng)式按指數(shù)進(jìn)行降冪排序。在這個(gè)程序模塊中,使用鏈表,根據(jù)對(duì)指數(shù)大小的比較,對(duì)各種情況進(jìn)行處理,此處由于反復(fù)使用指針對(duì)各個(gè)結(jié)點(diǎn)進(jìn)行定位,找到合適的位置再利用void Insert(Polyn p,Polyn h)進(jìn)行插入操作。(4)加、減、乘、除、的算法實(shí)現(xiàn): 在該程序中,最關(guān)鍵的一步是實(shí)現(xiàn)四則運(yùn)算和輸出,由于加減算法原則是一樣,減法可通過系數(shù)為負(fù)的加法實(shí)現(xiàn);對(duì)于乘除算法的大致流程都是:首先建立多項(xiàng)式a*b,a/b,然后使用鏈表存儲(chǔ)所求出的乘積,商和余數(shù)。這就實(shí)現(xiàn)了多項(xiàng)式計(jì)算模塊的主要功能。 (5)另一個(gè)子函數(shù)是輸出函數(shù) PrintPolyn(); 輸出最終的結(jié)果,算法是將最后計(jì)算合并的鏈表逐個(gè)結(jié)點(diǎn)依次輸出,便得到整鏈表,也就是最后的計(jì)算式計(jì)算結(jié)果。由于考慮各個(gè)結(jié)點(diǎn)的指數(shù)情況不同,分別進(jìn)行了判斷處理。 四、程序新點(diǎn) 通過多次寫程序,發(fā)現(xiàn)在程序在控制臺(tái)運(yùn)行時(shí)總是黑色的,本次寫程序就想著改變一下,于是經(jīng)過查資料利用system(“Color E0”);可以函數(shù)解決,這里“E0,”E是控制臺(tái)背景顏色,0是控制臺(tái)輸出字體顏色。 五、設(shè)計(jì)中遇到的問題及解決辦法 首先是,由于此次課程設(shè)計(jì)里使用指針使用比較多,自己在指針多的時(shí)候易腦子混亂出錯(cuò),對(duì)于此問題我是采取比較笨的辦法在稿紙上寫明白后開始進(jìn)行 4 代碼編寫。 其次是,在寫除法模塊時(shí)比較復(fù)雜,自己通過查資料最后成功寫出除法模塊功能。 最后是,前期分析不足開始急于寫代碼,中途出現(xiàn)各種問題,算是給自己以后設(shè)計(jì)時(shí)的一個(gè)經(jīng)驗(yàn)吧。 六、測(cè)試(程序截圖) 1.數(shù)據(jù)輸入及主菜單 2.加法和減法模塊 3.乘法和除法模塊 七、總結(jié) 通過本次應(yīng)用C語言設(shè)計(jì)一元多項(xiàng)式基本計(jì)算程序,使我更加鞏固了C語言程序設(shè)計(jì)的知識(shí),以前對(duì)指針這一點(diǎn)使用是比較模糊,現(xiàn)在通過此次課程設(shè)計(jì)對(duì)指針理解的比較深刻了。而且對(duì)于數(shù)據(jù)結(jié)構(gòu)的相關(guān)算法和函數(shù)的調(diào)用方面知識(shí)的加深。本次的課程設(shè)計(jì),一方面提高了自己獨(dú)立思考處理問題的能力;另一方面使自己再設(shè)計(jì)開發(fā)程序方面有了一定的小經(jīng)驗(yàn)和想法,對(duì)自己以后學(xué)習(xí)其他語言程序設(shè)計(jì)奠定了一定的基礎(chǔ)。 八、指導(dǎo)老師評(píng)語及成績(jī) 附錄:(課程設(shè)計(jì)代碼) #include float coef;6 int expn; struct Polynomial *next;} *Polyn,Polynomial; //Polyn為結(jié)點(diǎn)指針類型 void Insert(Polyn p,Polyn h){ if(p->coef==0)free(p); //系數(shù)為0的話釋放結(jié)點(diǎn) else { Polyn q1,q2; q1=h;q2=h->next; while(q2&&p->expn { q1=q2;q2=q2->next;} if(q2&&p->expn==q2->expn)//將指數(shù)相同相合并 { q2->coef+=p->coef; free(p); if(!q2->coef)//系數(shù)為0的話釋放結(jié)點(diǎn) { q1->next=q2->next;free(q2);} } else { p->next=q2;q1->next=p; }//指數(shù)為新時(shí)將結(jié)點(diǎn)插入 } 7 } //建立一個(gè)頭指針為head、項(xiàng)數(shù)為m的一元多項(xiàng)式 Polyn Create(Polyn head,int m){ int i; Polyn p; p=head=(Polyn)malloc(sizeof(struct Polynomial)); head->next=NULL; for(i=0;i { p=(Polyn)malloc(sizeof(struct Polynomial));//建立新結(jié)點(diǎn)以接收數(shù)據(jù) printf(“請(qǐng)輸入第%d項(xiàng)的系數(shù)與指數(shù):”,i+1); scanf(“%f %d”,&p->coef,&p->expn); Insert(p,head); //調(diào)用Insert函數(shù)插入結(jié)點(diǎn) } return head;} //銷毀多項(xiàng)式p void Destroy(Polyn p){ Polyn q1,q2; q1=p->next;8 q2=q1->next; while(q1->next) { free(q1); q1=q2;//指針后移 q2=q2->next; } } //輸出多項(xiàng)式p int Print(Polyn P){ Polyn q=P->next; int flag=1;//項(xiàng)數(shù)計(jì)數(shù)器 if(!q)//若多項(xiàng)式為空,輸出0 { putchar('0'); printf(“n”); return; } while(q) { if(q->coef>0&&flag!=1)putchar('+');//系數(shù)大于0且不是第一項(xiàng) 9 if(q->coef!=1&&q->coef!=-1)//系數(shù)非1或-1的普通情況 { printf(“%g”,q->coef); if(q->expn==1)putchar('X'); else if(q->expn)printf(“X^%d”,q->expn); } else { if(q->coef==1){ if(!q->expn)putchar('1'); else if(q->expn==1)putchar('X'); else printf(“X^%d”,q->expn);} if(q->coef==-1){ if(!q->expn)printf(“-1”); else if(q->expn==1)printf(“-X”); else printf(“-X^%d”,q->expn);} } q=q->next; flag++; } printf(“n”);} int compare(Polyn a,Polyn b){ if(a&&b) { if(!b||a->expn>b->expn)return 1; else if(!a||a->expn else return 0; } else if(!a&&b)return-1;//a多項(xiàng)式已空,但b多項(xiàng)式非空 else return 1;//b多項(xiàng)式已空,但a多項(xiàng)式非空 } //求解并建立多項(xiàng)式a+b,返回其頭指針 Polyn Add(Polyn pa,Polyn pb){ Polyn qa=pa->next; Polyn qb=pb->next; Polyn headc,hc,qc; hc=(Polyn)malloc(sizeof(struct Polynomial));//建立頭結(jié)點(diǎn) 11 hc->next=NULL; headc=hc; while(qa||qb){ qc=(Polyn)malloc(sizeof(struct Polynomial)); switch(compare(qa,qb)) { case 1: qc->coef=qa->coef; qc->expn=qa->expn; qa=qa->next; break; case 0: qc->coef=qa->coef+qb->coef; qc->expn=qa->expn; qa=qa->next; qb=qb->next; break; case-1: qc->coef=qb->coef; qc->expn=qb->expn; qb=qb->next; break;12 } if(qc->coef!=0) { qc->next=hc->next; hc->next=qc; hc=qc; } else free(qc);//當(dāng)相加系數(shù)為0時(shí),釋放該結(jié)點(diǎn) } return headc;} //求解并建立多項(xiàng)式a-b,返回其頭指針 Polyn Subtract(Polyn pa,Polyn pb){ Polyn h=pb; Polyn p=pb->next; Polyn pd; while(p)//將pb的系數(shù)取反 { p->coef*=-1;p=p->next;} pd=Add(pa,h); for(p=h->next;p;p=p->next) //恢復(fù)pb的系數(shù) p->coef*=-1;13 return pd;} //求解并建立多項(xiàng)式a*b,返回其頭指針 Polyn Multiply(Polyn pa,Polyn pb){ Polyn hf,pf; Polyn qa=pa->next; Polyn qb=pb->next; hf=(Polyn)malloc(sizeof(struct Polynomial));//建立頭結(jié)點(diǎn) hf->next=NULL; for(;qa;qa=qa->next) { for(qb=pb->next;qb;qb=qb->next) { pf=(Polyn)malloc(sizeof(struct Polynomial)); pf->coef=qa->coef*qb->coef; pf->expn=qa->expn+qb->expn; Insert(pf,hf);//調(diào)用Insert函數(shù)以合并指數(shù)相同的項(xiàng) } } return hf;} //求解并建立多項(xiàng)式a/b,返回其頭指針 void Device(Polyn pa,Polyn pb){ Polyn hf,pf,temp1,temp2; Polyn qa=pa->next; Polyn qb=pb->next; hf=(Polyn)malloc(sizeof(struct Polynomial));//建立頭結(jié)點(diǎn),存儲(chǔ)商 hf->next=NULL; pf=(Polyn)malloc(sizeof(struct Polynomial));//建立頭結(jié)點(diǎn),存儲(chǔ)余數(shù) pf->next=NULL; temp1=(Polyn)malloc(sizeof(struct Polynomial)); temp1->next=NULL; temp2=(Polyn)malloc(sizeof(struct Polynomial)); temp2->next=NULL; temp1=Add(temp1,pa); while(qa!=NULL&&qa->expn>=qb->expn) { temp2->next=(Polyn)malloc(sizeof(struct Polynomial)); temp2->next->coef=(qa->coef)/(qb->coef); temp2->next->expn=(qa->expn)-(qb->expn); Insert(temp2->next,hf); pa=Subtract(pa,Multiply(pb,temp2));15 qa=pa->next; temp2->next=NULL; } pf=Subtract(temp1,Multiply(hf,pb)); pb=temp1; printf(“商是:”); Print(hf); printf(“余數(shù)是:”); Print(pf);} void main(){ int choose=1;int m,n,flag=0;system(“Color E0”);Polyn pa=0,pb=0,pc,pd,pf;//定義各式的頭指針,pa與pb在使用前付初值NULL printf(“請(qǐng)輸入A(x)的項(xiàng)數(shù):”);scanf(“%d”,&m);printf(“n”);pa=Create(pa,m);//建立多項(xiàng)式A printf(“n”);printf(“請(qǐng)輸入B(x)的項(xiàng)數(shù):”);16 scanf(“%d”,&n);printf(“n”);pb=Create(pb,n);//建立多項(xiàng)式B printf(“n”);printf(“**********************************************n”);printf(“* 多項(xiàng)式操作菜單 printf(”**********************************************n“);printf(”tt 1.輸出操作n“);printf(”tt 2.加法操作n“);printf(”tt 3.減法操作n“);printf(”tt 4.乘法操作n“);printf(”tt 5.除法操作n“);printf(”tt 6.退出操作n“);printf(”**********************************************n“);while(choose){ printf(”執(zhí)行操作:“); scanf(”%d“,&flag); switch(flag) { case 1: printf(”多項(xiàng)式A(x):“);Print(pa);*n”); printf(“多項(xiàng)式B(x):”);Print(pb); break; case 2: pc=Add(pa,pb); printf(“多項(xiàng)式A(x)+B(x):”);Print(pc); Destroy(pc);break; case 3: pd=Subtract(pa,pb); printf(“多項(xiàng)式A(x)-B(x):”);Print(pd); Destroy(pd);break; case 4: pf=Multiply(pa,pb); printf(“多項(xiàng)式A(x)*B(x):”); Print(pf); Destroy(pf); break; case 5: Device(pa,pb);18 break; case 6: exit(0); break; } } Destroy(pa); Destroy(pb);} 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì) 1.赫夫曼編碼器 設(shè)計(jì)一個(gè)利用赫夫曼算法的編碼和譯碼系統(tǒng),重復(fù)地顯示并處理以下項(xiàng)目,直到選擇退出為止。要求: 1)將權(quán)值數(shù)據(jù)存放在數(shù)據(jù)文件(文件名為data.txt,位于執(zhí)行程序的當(dāng)前目錄中) 2)初始化:鍵盤輸入字符集大小26、26個(gè)字符和26個(gè)權(quán)值(統(tǒng)計(jì)一篇英文文章中26個(gè)字母),建立哈夫曼樹; 3)編碼:利用建好的哈夫曼樹生成哈夫曼編碼; 4)輸出編碼(首先實(shí)現(xiàn)屏幕輸出,然后實(shí)現(xiàn)文件輸出); 5)界面優(yōu)化設(shè)計(jì)。 代碼如下: #include typedef struct HTNode //結(jié)構(gòu)體 { int Weight; char ch;int Parent,Lchild,Rchild;}HTNode;typedef char * * HCode; void Save(int n,HTNode *HT) //把權(quán)值保存到文件 { FILE * fp; int i; if((fp=fopen(“data.txt”,“wb”))==NULL) { printf(“cannot open filen”); return; } for(i=0;i if(fwrite(&HT[i].Weight,sizeof(struct HTNode),1,fp)!=1) printf(“file write errorn”); fclose(fp); system(“cls”); printf(“保存成功!”); } void Create_H(int n,int m,HTNode *HT) //建立赫夫曼樹,進(jìn)行編碼 { int w,k,j;char c;for(k=1;k<=m;k++){ if(k<=n) { printf(“n請(qǐng)輸入權(quán)值和字符(用空格隔開): ”); scanf(“%d”,&w); scanf(“ %c”,&c);HT[k].ch=c; HT[k].Weight=w; } else HT[k].Weight=0; HT[k].Parent=HT[k].Lchild=HT[k].Rchild=0;} int p1,p2,w1,w2; for(k=n+1;k<=m;k++){ p1=0;p2=0; w1=32767;w2=32767; for(j=1;j<=k-1;j++) { if(HT[j].Parent==0) { if(HT[j].Weight { w2=w1;p2=p1; w1=HT[j].Weight; p1=j; } else if(HT[j].Weight { w2=HT[j].Weight; p2=j; } } } HT[k].Lchild=p1;HT[k].Rchild=p2;HT[k].Weight=HT[p1].Weight+HT[p2].Weight; HT[p1].Parent=k;HT[p2].Parent=k; } printf(“輸入成功!”);} void Coding_H(int n,HTNode *HT) //對(duì)結(jié)點(diǎn)進(jìn)行譯碼 { int k,sp,fp,p;char *cd;HCode HC; HC=(HCode)malloc((n+1)*sizeof(char *)); cd=(char *)malloc(n*sizeof(char));cd[n-1]='
第二篇:數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告n維矩陣乘法
第三篇:數(shù)據(jù)結(jié)構(gòu)稀疏矩陣應(yīng)用
第四篇:2012數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)
第五篇:數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)