《西工大數(shù)據(jù)結構實驗報告 矩陣運算》由會員分享,可在線閱讀,更多相關《西工大數(shù)據(jù)結構實驗報告 矩陣運算(11頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、《數(shù)據(jù)結構》實驗報告
一.實驗題目
必做:稀疏矩陣轉置、加法(行邏輯鏈接表)
選做:稀疏矩陣乘法
二.程序設計
(一) 需求分析
1.程序運行步驟:
(1)開始;
(2)選擇要進行的運算:1.矩陣轉置2.矩陣加法3.矩陣乘法;
(3)選擇矩陣運算后,輸入矩陣;
(4)對矩陣進行相應的運算;
(5)輸出運算結果;
(6)結束。
(二)概要設計
程序模塊及思想:
1.主函數(shù)
主函數(shù)的主體是一個switch選擇結構。內(nèi)部分為三種情況:矩陣轉置、矩陣加法和矩陣乘法。
(1) 矩陣轉置運算:
(1) 輸入矩陣;
(2) 輸出這個矩陣;
(3) 轉置這個矩陣
2、;
(4) 輸出轉置后的結果;
(5) 結束。
(2) 矩陣加法運算:
(1) 輸入矩陣A和矩陣B;
(2) 輸出這兩個矩陣;
(3) 將兩個矩陣相加;
(4) 輸出相加后的結果;
(5) 結束。
(3) 矩陣乘法運算:
(1)輸入矩陣A和矩陣B;
(2)輸出這兩個矩陣;
(3)將兩個矩陣相加;
(4)輸出相加后的結果;
(5)結束。
2.基本操作。
typedef struct {
int i,j;
ElemType e;
}Triple;
操作結果:定義三元組
typedef struct {
3、
Triple data[MAXSIZE+1];
int mu,nu,tu,cnum[MAXSIZE+1],rnum[MAXSIZE+1],cpot[MAXSIZE+1],rpos[MAXSIZE+1];
//某一列非零元的個數(shù),某一行非零元的個數(shù),某一列第一個非零元在b.data中的位置,某一行非零元在b.data中的位置
}TSMatrix;
操作結果:定義稀疏矩陣
int GetSMatrix(TSMatrix &t)
操作結果:創(chuàng)建稀疏矩陣,以三元組表形式儲存
int TransposeSMatrix(TSMatrix M,TSMat
4、rix &T)
操作結果:轉置矩陣
int PrintSMatrix(TSMatrix t)
操作結果:輸出矩陣
int AddSMatrix(TSMatrix t,TSMatrix s,TSMatrix &a)
操作結果:矩陣相加
(三)詳細設計
1.結構體定義
typedef struct {
int i,j; //行,列
ElemType e; //非零元素的值
}Triple;
操作結果:定義三元組
typedef struct {
Triple data[MAXSIZE+1];
int
5、 mu,nu,tu,cnum[MAXSIZE+1],rnum[MAXSIZE+1],cpot[MAXSIZE+1],rpos[MAXSIZE+1];
//行數(shù),列數(shù),非零元素個數(shù),某一列非零元的個數(shù),某一行非零元的個數(shù),某一列第一個非零元在b.data中的位置,某一行非零元在b.data中的位置
}TSMatrix;
操作結果:定義稀疏矩陣
2.每個模塊的分析:
(1) 主程序模塊:
int main()
{
int k;
TSMatrix t,s,a;
printf("請輸入需要執(zhí)行的操作的序號:(1.矩陣轉置 2.矩陣相加 3.
6、矩陣乘法)\n");
scanf("%d",&k);
switch(k)
{
case(1): {
GetSMatrix(t); //轉置模塊
printf("輸入的矩陣為:\n");
PrintSMatrix(t);
TransposeSMatrix(t,s);
printf("轉置后的矩陣為:\n");
PrintSMatrix(s);
}break;
case(2): {
printf("請依次輸入兩個矩陣\n"); //加法
7、模塊
GetSMatrix(t);
printf("\n\n");
GetSMatrix(s);
printf("輸入的兩個矩陣分別為:\n");
printf("矩陣a:\n");
PrintSMatrix(t);
printf("矩陣b:\n");
PrintSMatrix(s);
if(t.mu!=s.mu||t.nu!=s.nu) printf("ERROR");
else {
AddSMatrix(t,s,a);
printf("相加后的矩陣為:\n");
PrintSMatri
8、x(a);
}
} break;
case(3): {
printf("請依次輸入兩個矩陣\n"); //乘法模塊
GetSMatrix(t);
printf("\n\n");
GetSMatrix(s);
printf("輸入的兩個矩陣分別為:\n");
printf("矩陣a:\n");
PrintSMatrix(t);
printf("矩陣b:\n");
PrintSMatrix(s);
if(t.nu!=s.mu) printf("ERROR\n");
else
9、{
MultSMatrix(t,s,a);
printf("相乘后的矩陣為:\n");
PrintSMatrix(a);
}
} break;
return 0;
}
}
(2) 基本操作函數(shù):
(1) 矩陣的創(chuàng)建:
int GetSMatrix(TSMatrix &t) { //創(chuàng)建稀疏矩陣,以三元組表形式儲存
int i,k;
um[0]=0;
t.cpot[0]=1;
t.rnum[0]=0,t.rpos[0]=1; //第零列非零元的個數(shù),第零行非零元的個數(shù),第零列第一個非零元在b.data
10、中的位置,第零行非零元在b.data中的位置等參數(shù)的初始值為零
printf("請輸入矩陣的行數(shù)、列數(shù)以及非零元個數(shù):\n");
scanf("%d %d %d",&t.mu,&t.nu,&t.tu);
printf("請依次輸入%d個非零元的行數(shù)、列數(shù)以及非零元的值:\n",t.tu);
for (i=1;i<=t.tu;i++) {
scanf("%d %d %d",&t.data[i].i,&t.data[i].j,&t.data[i].e); //輸入每個非零元素的行坐標,列坐標和值
}
for(i=1;i<=t.nu;i++)
11、 {
t.cpot[i]=t.cpot[i-1]+um[i-1]; //某一列第一個非零元素在t.data中的位置等于上一列第一個非零元在t.data中的位置加上上一列的非零元個數(shù)
um[i]=0; //這一列非零元的個數(shù)初始值為零
for(k=1;k<=t.tu;k++)
if(t.data[k].j==i) um[i]+=1; //求這一列非零元的個數(shù)
}
for(i=1;i<=t.mu;i++) {
t.rpos[i]=t.rpos[i-1]+t.rnum[i-1]; //某一行第一個非零元在t.data的位置
12、等于上一行第一個非零元在t.data中的位置加上上一行的非零元個數(shù)
t.rnum[i]=0; //這一行非零元的個數(shù)初始值為零
for(k=1;k<=t.tu;k++)
if(t.data[k].i==i) t.rnum[i]+=1; //求這一行非零元的個數(shù)
}
return OK;
}
(2)矩陣的轉置
int TransposeSMatrix(TSMatrix M,TSMatrix &T) { //轉置矩陣
T.mu=M.nu; //T的行數(shù)與M的列數(shù)相同
T.nu=M.mu;
13、 //T的列數(shù)與M的列數(shù)相同
T.tu=M.tu;
int col,p,q;
if(T.tu){
q=1;
for(col=1;col<=M.nu;++col)
for(p=1;p<=M.tu;++p)
if(M.data[p].j == col){
T.data[q].i = M.data[p].j; //將轉置后的矩陣M的賦值給T
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
++q;
}
}
return OK
14、;
}
(3) 矩陣的加法:
int AddSMatrix(TSMatrix t,TSMatrix s,TSMatrix &a) { //矩陣相加
int i,k,j,q=1;
a.mu=t.mu;
a.nu=t.nu;
a.tu=0; //S,T矩陣的行列必須相同
for(i=1;i<=t.mu;i++) {
k=t.rpos[i]; j=s.rpos[i]; //k,j分別等于每一列第一個非零元在的T.data和s.data中的位置
if(i==t.mu) {
15、 //如果i等于行數(shù)
t.rpos[i+1]=t.rpos[i]+t.tu-k+1; //下一行第一個非零元在t.data中的位置等于總非零元的個數(shù)加一
s.rpos[i+1]=s.rpos[i]+s.tu-j+1; //求下一行第一個非零元在s.data中的位置
}
while(k
16、f(t.data[k].j
17、=i;
a.data[q].j=s.data[j].j;
a.data[q].e=s.data[j].e;
q++;j++;
a.tu++;
}
}
else
{ //當T與S列行坐標相等時
a.data[q].i=i;
a.data[q].j=t.data[k].j;
a.data[q].e=t.data[k].e+s.data[j].e;
q++;
k++;
18、//相加
j++;
a.tu++;
}
}
while(k
19、i;
a.data[q].j=s.data[j].j; // a.data[q]賦值為s.data[q]
a.data[q].e=s.data[j].e;
q++;
j++;
a.tu++;
}
}
return OK;
}
(4) 矩陣的乘法
int MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q){
int arow,brow,ccol,ctemp[MAXSIZE+1],tp,t,p,q,i;
if(M.nu!=N.mu) return E
20、RROR;
Q.mu=M.mu;
Q.nu=N.nu; //確定矩陣的參數(shù)
Q.tu=0;
if(M.tu*N.tu!=0){
for(arow=1;arow<=M.mu;++arow){
for(i=1;i<=N.nu;i++) ctemp[i]=0; //累加器清零
Q.rpos[arow] = Q.tu+1; //每一個Q.rpos[arow]賦相同的初值Q.tu+1。
21、
if(arow
22、 //遍歷M的一行元素,[M.rpos[arow],tp],驅動元素M.data[p]
brow=M.data[p].j;
if(brow
23、col]+=M.data[p].e*N.data[q].e;
}
}
for(ccol=1;ccol<=Q.nu;++ccol)
if(ctemp[ccol]){ //新的矩陣
if(++Q.tu > MAXSIZE) return ERROR;
Q.data[Q.tu].i=arow;
Q.data[Q.tu].j=ccol;
Q.data[Q.tu].e=ctemp[ccol];
24、
}
}
}
return OK;
}
(四) 程序使用說明及測試結果
程序運行截圖如下:
1.矩陣轉置
(2)矩陣加法:
(3)矩陣乘法:
(五)、實驗總結(實驗心得)
1.你在編程過程中花時多少?
答:從設計到編寫,從調(diào)試到完成,直至最終完成實驗報告一共用了約八個小時。
2.多少時間在紙上設計?
答:兩個小時。
3.多少時間上機輸入和調(diào)試?
答:四個多小時。
4.多少時間在思考問題?
答:設計前就思考,直至完成報告,十個小時。
5.遇到了哪些難題?又是怎么克服的?
25、
答:答:在做這項作業(yè)時。我可以說自己遇到了無數(shù)難題,以為我的C語言成績并不好,棧的熟悉度恐怕只有10%。因此完成這項作業(yè)的過程可謂艱辛。
首先遇到的困難就是設計程序。去年C語言學得很不扎實,我對三元組的結構都不甚了解,更別說運用與之相關的算法了。在設計程序之前:我花了很長時間復習書上與之相關的算法。在周五下午數(shù)據(jù)結構的實驗課上,我又將數(shù)據(jù)結構書上的算法仔細分析了一遍。由于知識的匱乏,我只能先將書上的三元組稀疏矩陣有關的算法逐句逐句的分析,?然后在紙上設計相應的流程。最后憑借自己的知識,并利用同學的幫助,磕磕絆絆地編寫了程序。
接下來的困難,也就是最大,最麻煩,解決起來最耗費腦力,最枯燥乏
26、味的問題——調(diào)試程序。最初的程序編譯之后,問題觸目驚心,我根據(jù)系統(tǒng)的提示,首先補上了缺失的間隔符,又定義了遺漏的變量,再次編譯,錯誤有所減少,但依然多,我又重新修改。接下來的錯誤越來越“高級”,數(shù)據(jù)類型,返回類型,函數(shù)類型等有關。我便循環(huán)往復,不厭其煩地修改,每當減少一個錯誤,我都會有幾分高興,而有的時候,修改后會產(chǎn)生更多的錯誤。
就這樣一遍又一遍,終于系統(tǒng)顯示沒有錯誤和警告了。我運行了程序。當我按照自己的設想將輸入數(shù)據(jù)時,敲下回車鍵后結果卻令我傻了眼。屏幕上沒有任何顯示。,原來許多錯誤是編譯器沒有檢測出來。
最終通過我的調(diào)試,修改和同學的幫助,終于完成了程序。
???
6.你的收獲有哪些?
答:首先,我對稀疏矩陣的知識有了更多了解破除了錯誤的認識。
其次,通過這次作業(yè),我掌握了幾種與稀疏矩陣有關的算法。
最后,我還溫習了有關C語言的許多知識。
參考文獻:【1】嚴蔚敏?《數(shù)據(jù)結構?第三章》清華大學出版社