版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、<p><b> 稀疏矩陣應(yīng)用</b></p><p> 摘 要 本課程設(shè)計主要實現(xiàn)在三元組存儲結(jié)構(gòu)與十字鏈表存儲結(jié)構(gòu)下輸入稀疏矩陣,并對稀疏矩陣進(jìn)行轉(zhuǎn)置,相加,相乘操作,最后輸出運(yùn)算后的結(jié)果。在程序設(shè)計中,考慮到方法的難易程度,采用了先用三元組實現(xiàn)稀疏矩陣的輸入,輸出,及其轉(zhuǎn)置,相加,相乘操作的方法,再在十字鏈表下實現(xiàn)。程序通過調(diào)試運(yùn)行,結(jié)果與預(yù)期一樣,初步實現(xiàn)了設(shè)計目標(biāo)
2、。</p><p> 關(guān)鍵詞 程序設(shè)計;稀疏矩陣;三元組;十字鏈表</p><p><b> 1 引言</b></p><p><b> 課程設(shè)計任務(wù)</b></p><p> 本課程設(shè)計主要實現(xiàn)在三元組存儲結(jié)構(gòu)與十字鏈表存儲結(jié)構(gòu)下輸入稀疏矩陣,并對稀疏矩陣進(jìn)行轉(zhuǎn)置,相加,相乘操作,最后輸
3、出運(yùn)算后的結(jié)果。稀疏矩陣采用三元組和十字鏈表表示,并在兩種不同的存儲結(jié)構(gòu)下,求兩個具有相同行列數(shù)的稀疏矩陣A和B的相加矩陣C,并輸出C; 求出A的轉(zhuǎn)置矩陣D,輸出D; 求兩個稀疏矩陣A和B的相乘矩陣E,并輸出E。</p><p><b> 課程設(shè)計性質(zhì)</b></p><p> 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計是重要地實踐性教學(xué)環(huán)節(jié)。在進(jìn)行了程序設(shè)計語言課和《數(shù)據(jù)結(jié)構(gòu)》課程教學(xué)的
4、基礎(chǔ)上,設(shè)計實現(xiàn)相關(guān)的數(shù)據(jù)結(jié)構(gòu)經(jīng)典問題,有助于加深對數(shù)據(jù)結(jié)構(gòu)課程的認(rèn)識。本課程設(shè)計是數(shù)據(jù)結(jié)構(gòu)中的一個關(guān)于稀疏矩陣的算法的實現(xiàn),包括在三元組和十字鏈表下存儲稀疏矩陣,并對輸入的稀疏矩陣進(jìn)行轉(zhuǎn)置,相加,相乘等操作,最后把運(yùn)算結(jié)果輸出。此課程設(shè)計要求對數(shù)組存儲結(jié)構(gòu)和鏈表存儲結(jié)構(gòu)非常熟悉,并能熟練使用它們。</p><p><b> 1.3課程設(shè)計目的</b></p><p&g
5、t; 其目的是讓我們在學(xué)習(xí)完C、數(shù)據(jù)結(jié)構(gòu)等課程基礎(chǔ)上,掌握多維數(shù)組的邏輯結(jié)構(gòu)和存儲結(jié)構(gòu)、掌握稀疏矩陣的壓縮存儲及轉(zhuǎn)置,相加,相乘等基本操作,并用不同的方法輸出結(jié)果,進(jìn)一步掌握設(shè)計、實現(xiàn)較大系統(tǒng)的完整過程,包括系統(tǒng)分析、編碼設(shè)計、系統(tǒng)集成、以及調(diào)試分析,熟練掌握數(shù)據(jù)結(jié)構(gòu)的選擇、設(shè)計、實現(xiàn)以及操作方法,為進(jìn)一步的應(yīng)用開發(fā)打好基礎(chǔ)。</p><p><b> 需求分析</b></p>
6、;<p> 2.1設(shè)計函數(shù)建立稀疏矩陣及初始化值和輸出稀疏矩陣的值</p><p> 本模塊要求設(shè)計函數(shù)建立稀疏矩陣并初始化,包括在三元組結(jié)構(gòu)下和十字鏈表結(jié)構(gòu)下。首先要定義兩種不同的結(jié)構(gòu)體類型,在創(chuàng)建稀疏矩陣時,需要設(shè)計兩個不同的函數(shù)分別在三元組和十字鏈表下創(chuàng)建稀疏矩陣,在輸入出現(xiàn)錯誤時,能夠?qū)﹀e誤進(jìn)行判別處理,初始化稀疏矩陣都為空值,特別注意在十字鏈表下,對變量進(jìn)行動態(tài)的地址分配。在設(shè)計輸出稀
7、疏矩陣的值的函數(shù)時,也要針對兩種不同的情況,分別編制函數(shù),才能準(zhǔn)確的輸出稀疏矩陣。在對稀疏矩陣進(jìn)行初始化及輸出值時,均只輸出非零元素的值和它所在的所在行及所在列。</p><p> 2.2構(gòu)造函數(shù)進(jìn)行稀疏矩陣的轉(zhuǎn)置并輸出結(jié)果</p><p> 本模塊要求設(shè)計函數(shù)進(jìn)行稀疏矩陣的轉(zhuǎn)置并輸出轉(zhuǎn)置后的結(jié)果,由于對稀疏函數(shù)的轉(zhuǎn)置只對一個矩陣進(jìn)行操作,所以實現(xiàn)起來難度不是很大,函數(shù)也比較容易編寫。
8、在編寫函數(shù)時,要先定義一個相應(yīng)的結(jié)構(gòu)體變量用于存放轉(zhuǎn)置后的矩陣,最后把此矩陣輸出。</p><p> 2.3構(gòu)造函數(shù)進(jìn)行兩個稀疏矩陣相加及相乘并輸出最終的稀疏矩陣</p><p> 本模塊要求設(shè)計相加和相乘函數(shù)對兩個矩陣進(jìn)行運(yùn)算,并輸出最終的稀疏矩陣,在進(jìn)行運(yùn)算前,要對兩個矩陣進(jìn)行檢查,看是不是相同類型的矩陣,因為兩個矩陣相加要求兩個矩陣一定是同一類型的矩陣,定義相應(yīng)的矩陣類型用于存放
9、兩個矩陣相加相乘后的結(jié)果矩陣,這個結(jié)果矩陣的行數(shù)列數(shù)需要綜合多方面情況來確定。這四個函數(shù)也是整個程序的難點,需要靈活運(yùn)用數(shù)組及指針的特點。</p><p><b> 2.4退出系統(tǒng)</b></p><p> 本模塊要求設(shè)置選項能隨時結(jié)束程序的運(yùn)行,本程序中采用exit(0)函數(shù)。程序以用戶和計算機(jī)的對話方式執(zhí)行,即在計算機(jī)終端上顯示“提示信息”之后,由用戶在鍵盤上
10、輸入演示程序中需要的相關(guān)信息及命令。</p><p><b> 概要設(shè)計</b></p><p><b> 3.1主界面設(shè)計</b></p><p> 為了實現(xiàn)在兩種存儲結(jié)構(gòu)下對稀疏矩陣的多種算法功能的管理,首先設(shè)計一個含有多</p><p> 個菜單項的主控菜單子程序以鏈接系統(tǒng)的各項子功能
11、,方便用戶交互式使用本系統(tǒng)。本系</p><p> 統(tǒng)主控菜單運(yùn)行界面如圖1所示。</p><p><b> 圖1主界面圖</b></p><p><b> 3.2存儲結(jié)構(gòu)設(shè)計</b></p><p> 本系統(tǒng)采用三元組結(jié)構(gòu)和十字鏈表結(jié)構(gòu)存儲稀疏矩陣的具體信息。其中:在三元組中,所有元素的信
12、息用數(shù)組表示,每個數(shù)組元素中包含有行下標(biāo)(i),列下標(biāo)(j)和對應(yīng)的數(shù)值(e),它們是整型數(shù)據(jù),全部的信息用在十字鏈表中,全部結(jié)點的信息用結(jié)構(gòu)體(TSMatrix)包含,包括用數(shù)組(Triple data[MAXSIZE])和總共的行數(shù)(mu),列數(shù)(nu)以及非零元素的個數(shù)(tu)。在十字鏈表下,頭結(jié)點為指針數(shù)組的十字鏈表存儲;每個結(jié)點里面包含行下標(biāo)(i),列下標(biāo)(j)和對應(yīng)的數(shù)值(e),它們是整型數(shù)據(jù),還有兩個指針(right)、(
13、down),屬于OLNode結(jié)構(gòu)體。全部的信息用結(jié)構(gòu)體(crosslist)包含,包括指針數(shù)組(OLink* rhead和*chead)和總共的行數(shù)(mu),列數(shù)(nu)以及非零元素的個數(shù)(tu)。</p><p><b> 三元組結(jié)構(gòu)體定義:</b></p><p> typedef struct{</p><p><b>
14、int i,j;</b></p><p><b> int e;</b></p><p><b> }Triple;</b></p><p> typedef struct{</p><p> Triple data[MAXSIZE];</p><p>
15、 int rpos[MAXSIZE + 1]; </p><p> int nu,mu,tu;</p><p> }TSMatrix; </p><p> 十字鏈表結(jié)構(gòu)體定義: </p><p> typedef struct OLNode{</p><p><b> int i
16、,j;</b></p><p><b> int e;</b></p><p> struct OLNode *right,*down;</p><p> }OLNode,*OLink;</p><p> typedef struct {</p><p> int mu,nu
17、,tu;</p><p> OLink *rhead,*chead;</p><p> }CrossList; </p><p><b> 3.3系統(tǒng)功能設(shè)計</b></p><p> 本系統(tǒng)除了要完成分別在三元組存儲結(jié)構(gòu)以及在十字鏈表下實現(xiàn)稀疏矩陣的初始化功能外還設(shè)置了4個子功能菜單。稀疏矩陣的建立及初始化在三
18、元組存儲結(jié)構(gòu)下,由函數(shù) void CreateSMatrix(TSMatrix &M)實現(xiàn),在十字鏈表存儲結(jié)構(gòu)下,由函數(shù)void CreateSMatix_OL(CrossList &M)依據(jù)讀入的行數(shù)和列數(shù)以及非零元素的個數(shù),分別設(shè)定每個非零元素的信息。4個子功能的設(shè)計描述如下。</p><p> ?。?)稀疏矩陣的轉(zhuǎn)置:</p><p> 此功能在三元組存儲結(jié)構(gòu)下,由
19、函數(shù)void TransposeSMatrix(TSMatrix M,TSMatrix &T)實現(xiàn),在十字鏈表存儲結(jié)構(gòu)下,由函數(shù)void TurnSMatrix_OL(CrossList &M)實現(xiàn)。當(dāng)用戶選擇該功能,系統(tǒng)提示用戶初始化一個矩陣,然后進(jìn)行轉(zhuǎn)置,最終輸出結(jié)果。</p><p> ?。?)稀疏矩陣的加法:</p><p> 此功能在三元組存儲結(jié)構(gòu)下,由函數(shù)
20、void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S)實現(xiàn),在十字鏈表存儲結(jié)構(gòu)下,由函數(shù)int SMatrix_ADD(CrossList *A,CrossList *B)實現(xiàn)。當(dāng)用戶選擇該功能,系統(tǒng)即提示用戶初始化要進(jìn)行加法的兩個矩陣的信息。然后進(jìn)行加法,最后輸出結(jié)果。</p><p> (3)稀疏矩陣的乘法:</p><p> 此
21、功能在三元組存儲結(jié)構(gòu)下,由函數(shù)int MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)實現(xiàn)。在十字鏈表存儲結(jié)構(gòu)下,由函數(shù)int MultSMatrix_OL(CrossList M, CrossList N, CrossList &Q)實現(xiàn)。當(dāng)用戶選擇該功能,系統(tǒng)提示輸入要進(jìn)行相乘的兩個矩陣的詳細(xì)信息。然后進(jìn)行相乘,最后得到結(jié)果。</p><p>
22、<b> (4)退出:</b></p><p> 即退出稀疏矩陣的應(yīng)用系統(tǒng),由exit(0)函數(shù)實現(xiàn)。當(dāng)用戶選擇該功能,則退出該稀疏矩陣的應(yīng)用系統(tǒng)。</p><p><b> 4 詳細(xì)設(shè)計</b></p><p> 4.1 數(shù)據(jù)類型定義</p><p><b> 三元組結(jié)構(gòu)體定義
23、:</b></p><p> typedef struct{ //三元組結(jié)構(gòu)體</p><p> int i,j; //行標(biāo)、列表</p><p> int e;
24、 //值 </p><p><b> }Triple;</b></p><p> typedef struct{</p><p> Triple data[MAXSIZE]; //三元組表</p><p> int rpos[MAXSIZE + 1]; &
25、lt;/p><p> int nu,mu,tu; //行數(shù)、列數(shù)、非零元個數(shù)</p><p> }TSMatrix; </p><p> 十字鏈表結(jié)構(gòu)體定義: </p><p> typedef struct OLNode{ /
26、/結(jié)點結(jié)構(gòu)</p><p> int i,j; //行標(biāo)、列標(biāo) </p><p> int e; //值</p><p> struct OLNode *right,*down; //同
27、一行、列的下一個結(jié)點</p><p> }OLNode,*OLink;</p><p> typedef struct {</p><p> int mu,nu,tu; //行數(shù)、列數(shù)、非零元個數(shù)</p><p> OLink *rhead,*chead;
28、 //行、列指針基指</p><p> }CrossList; </p><p> 4.2系統(tǒng)主要子程序詳細(xì)設(shè)計</p><p> A. 主程序模塊設(shè)計:</p><p> void main(){</p><p><b> int n,i;</b><
29、/p><p> TSMatrix M,T,S; //聲明三個三元組數(shù)組</p><p> CrossList MM,TT,SS; //聲明三個十字鏈表</p><p> printf(" ***稀疏矩陣應(yīng)用***");</p><p> printf("
30、;\n請你選擇創(chuàng)建稀疏矩陣的方法:\n1:用三元組創(chuàng)建稀疏矩陣\n2:用十字鏈表創(chuàng)建稀疏矩陣\n3:退出程序");</p><p> printf("\n");</p><p> scanf("%d",&n);</p><p> switch(n){</p><p><b&
31、gt; case 1:</b></p><p> CreateSMatrix(M); //創(chuàng)建三元組矩陣</p><p> printf("您輸入的稀疏矩陣為(只列出非零元素):\n 行 列 大小\n");</p><p> ShowTMatrix(M); /
32、/顯示三元組矩陣</p><p> printf("已經(jīng)選擇三元組創(chuàng)建稀疏矩陣,請選擇操作:\n1:稀疏矩陣轉(zhuǎn)置\n2:稀疏矩陣相加\n3:稀疏矩陣相乘\n4:退出程序\n");</p><p> scanf("%d",&i);</p><p> switch(i){</p><p>
33、case 1:TransposeSMatrix(M,T); //對三元組矩陣進(jìn)行轉(zhuǎn)置</p><p> printf("轉(zhuǎn)置后的矩陣為(只列出非零元素):\n 行 列 大小\n");</p><p> ShowTMatrix(T);</p><p><b> break;</b></p>&l
34、t;p> case 2:printf("請你輸入另一個稀疏矩陣:");</p><p> CreateSMatrix(T);</p><p> AddTMatix(M,T,S); //兩個三元組矩陣相加</p><p> printf("相加后的矩陣為(只列出非零元素):\n 行 列 大小\n&
35、quot;);</p><p> ShowTMatrix(S);</p><p><b> break;</b></p><p> case 3:printf("請你輸入另一個稀疏矩陣:");</p><p> CreateSMatrix(T);</p><p> M
36、ultSMatrix(M,T,S); //兩個三元組矩陣相乘</p><p> printf("相乘后的矩陣為(只列出非零元素):\n 行 列 大小\n");</p><p> ShowTMatrix(S);</p><p><b> break;</b></p><p>
37、; case 4:exit(0);};break;</p><p> case 2:{CreateSMatix_OL(MM); //創(chuàng)建十字鏈表矩陣</p><p> printf("您輸入的稀疏矩陣為(只列出非零元素):\n 行 列 大小\n");</p><p> ShowMAtrix(&MM); /
38、/顯示十字鏈表矩陣</p><p> printf("已經(jīng)選擇十字鏈表創(chuàng)建稀疏矩陣,請選擇操作: 1:稀疏矩陣轉(zhuǎn)置\n 2:稀疏矩陣相加\n 3:稀疏矩陣相乘\n 4:退出程序\n");</p><p> scanf("%d",&i);</p><p> switch(i){</p><
39、p><b> case 1:</b></p><p> TurnSMatrix_OL(MM); //十字鏈表矩陣轉(zhuǎn)置</p><p> printf("轉(zhuǎn)置后的矩陣為(只列出非零元素):\n 行 列 大小\n");</p><p> ShowMAtrix(&MM);</p&
40、gt;<p><b> break;</b></p><p><b> case 2:</b></p><p> printf("請你輸入另一個稀疏矩陣:");</p><p> CreateSMatix_OL(TT);</p><p> SMatrix_
41、ADD(&MM,&TT); //兩個十字鏈表矩陣相加 </p><p> printf("相加后的矩陣為(只列出非零元素):\n 行 列 大小\n");</p><p> ShowMAtrix(&MM);break;</p><p> case 3:printf("請你輸入另一個稀疏矩陣:&
42、quot;);</p><p> CreateSMatix_OL(TT);</p><p> MultSMatrix_OL(MM,TT,SS); //兩個十字鏈表矩陣相乘</p><p> printf("相乘后的矩陣為(只列出非零元素):\n 行 列 大小\n");</p><p> ShowM
43、Atrix(&SS);break;</p><p> case 4:exit(0);</p><p><b> }};break;</b></p><p> case 3:exit(0);</p><p> default :printf("erorr");</p>&l
44、t;p><b> }</b></p><p><b> }</b></p><p> B. 稀疏矩陣操作各子函數(shù)的定義:</p><p> (1)建立與初始化稀疏矩陣:</p><p> void CreateSMatrix(TSMatrix &M){//采用三元組順序表存儲
45、表示,創(chuàng)建稀疏矩陣M </p><p> printf("請輸入稀疏矩陣的行數(shù)、列數(shù)和非零元個數(shù):");</p><p> scanf("%d%d%d",&M.mu,&M.nu,&M.tu);</p><p> if((M.mu<=0)||(M.nu<=0)||(M.tu<=0)
46、||(M.tu>M.mu*M.nu))</p><p> //判斷行值、列值、元素個數(shù)是否合法</p><p> printf("輸入有誤!");</p><p> for(int i=1;i<=M.tu;i++){//輸入稀疏矩陣元素</p><p> printf("請輸入元素坐標(biāo)(所在行
47、,所在列)及大?。?quot;);</p><p> scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);</p><p> if((M.data[i].i<=0)||(M.data[i].j<=0)){</p><p> printf("
48、;輸入錯誤,請重新輸入");</p><p> scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);</p><p><b> }</b></p><p><b> }</b></p><
49、;p> int num[100];</p><p><b> if(M.tu)</b></p><p><b> {int i;</b></p><p> for(i = 1; i <= M.mu; i++) num[i] = 0;//初始化</p><p> for(int
50、t = 1; t <= M.tu; t++) ++num[M.data[t].i];</p><p> //求M中每一行含非零元素個數(shù)</p><p><b> //求rpos</b></p><p> M.rpos[1] = 1;</p><p> for(i = 2; i <= M.mu; i++
51、) M.rpos[i] = M.rpos[i-1] + num[i-1];</p><p><b> }</b></p><p><b> } //創(chuàng)建三元組</b></p><p> int CreateSMatix_OL(CrossList &M){</p><p> int i
52、,j,e;</p><p><b> OLink q;</b></p><p><b> OLink p;</b></p><p> printf("請輸入稀疏矩陣的行數(shù),列數(shù),非零元素的個數(shù)"); //矩陣行數(shù),列數(shù)下標(biāo)均從開始;</p><p> scanf(&
53、quot;%d%d%d",&M.mu,&M.nu,&M.tu);</p><p> M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLNode));//分配內(nèi)存空間</p><p> M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLNode));//分配內(nèi)存空間</p>
54、<p> for( i=1;i<=M.mu;i++)M.rhead[i]=NULL;//把矩陣每個元素置空值</p><p> for( i=1;i<=M.nu;i++)M.chead[i]=NULL;</p><p> printf("請輸入稀疏矩陣,如果行為,則退出\n");</p><p> scanf(&q
55、uot;%d%d%d",&i,&j,&e);</p><p> while(i!=0){</p><p> p=(OLink)malloc(sizeof(OLNode));</p><p> p->i=i;p->j=j;p->e=e;</p><p> if(M.rhead[i]==
56、NULL||M.rhead[i]->j>j){p->right=M.rhead[i];M.rhead[i]=p;}</p><p><b> else{</b></p><p> q=M.rhead[i];</p><p> while(q->right&&q->right->j<
57、j)q=q->right;</p><p> p->right=q->right;</p><p> q->right=p;}</p><p> if(M.chead[j]==NULL||M.chead[j]->i>i){p->down=M.chead[j];M.chead[j]=p;}</p><
58、p><b> else{</b></p><p> q=M.chead[j];</p><p> while(q->down&&q->down->i<i)q=q->down;</p><p> p->down=q->down;</p><p> q
59、->down=p;</p><p><b> }</b></p><p> scanf("%d%d%d",&i,&j,&e);</p><p><b> }</b></p><p><b> return 1;</b>&
60、lt;/p><p><b> }//創(chuàng)建十字鏈表</b></p><p> ?。?)輸出稀疏矩陣:</p><p> void ShowTMatrix(TSMatrix M){</p><p> for(int col=1;col<=M.mu;col++)</p><p> //通過雙重
61、循環(huán),把稀疏矩陣中不為零的元素的行數(shù)、列數(shù)和值顯示出來</p><p> for(int p=1;p<=M.tu;p++)</p><p> if(M.data[p].i==col)printf("%4d %4d %4d\n",M.data[p].i,M.data[p].j,M.data[p].e);</p><p><b>
62、 }//三元組顯示</b></p><p> int ShowMAtrix(CrossList *A){</p><p><b> int col;</b></p><p><b> OLink p;</b></p><p> for(col=1;col<=A->m
63、u;col++)if(A->rhead[col]){p=A->rhead[col];</p><p> //通過循環(huán),把A結(jié)點的rhead[col]賦給p</p><p> while(p){printf("%3d%3d%3d\n",p->i,p->j,p->e);p=p->right;}</p><p>
64、<b> }</b></p><p><b> return 1;</b></p><p><b> }//十字鏈表顯示</b></p><p> ?。?)實現(xiàn)矩陣的轉(zhuǎn)置:</p><p> void TransposeSMatrix(TSMatrix M,TSMatr
65、ix &T){</p><p> T.nu=M.mu;//T矩陣存放轉(zhuǎn)置后的矩陣</p><p> T.mu=M.nu;</p><p> T.tu=M.tu;</p><p><b> int q=1;</b></p><p> for(int col=1;col<=M.
66、nu;col++)//通過循環(huán),把非零元素的行數(shù)與列數(shù)進(jìn)行交換,實現(xiàn)轉(zhuǎn)置</p><p> for(int p=1;p<=M.tu;p++)</p><p> if(M.data[p].j==col){</p><p> T.data[q].i=M.data[p].j;</p><p> T.data[q].j=M.data[p
67、].i;</p><p> T.data[q].e=M.data[p].e;</p><p><b> q++;</b></p><p><b> }</b></p><p><b> }//三元組轉(zhuǎn)置</b></p><p> void
68、TurnSMatrix_OL(CrossList &M){</p><p> int col,row; //定義循環(huán)變量</p><p> OLink p,q; //定義OLink結(jié)構(gòu)類型變量</p><p> for(col=1;col<=M.mu;col++) //通過循環(huán),把非零元素的行數(shù)與列數(shù)進(jìn)行交換,實現(xiàn)轉(zhuǎn)置</p>
69、<p> { q=p=M.rhead[col];</p><p><b> while(q){</b></p><p><b> row=p->i;</b></p><p> p->i=p->j;</p><p><b> p->j=row
70、;</b></p><p> q=p->right;</p><p> p->right=p->down;</p><p> p->down=q;</p><p><b> }</b></p><p><b> }</b><
71、/p><p><b> }//十字鏈表轉(zhuǎn)置</b></p><p> ?。?)實現(xiàn)兩個矩陣的相加:</p><p> void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S){</p><p> //矩陣S存放相加后的矩陣</p><p> S
72、.mu=M.mu>T.mu?M.mu:T.mu;//對S矩陣的行數(shù)賦值</p><p> S.nu=M.nu>T.nu?M.nu:T.nu;//對S矩陣的列數(shù)賦值</p><p><b> S.tu=0;</b></p><p><b> int ce;</b></p><p>
73、 int q=1;int mcount=1,tcount=1;</p><p> while(mcount<=M.tu&&tcount<=T.tu){</p><p> switch(Compare(M.data[mcount].i,M.data[mcount].j,T.data[tcount].i,T.data[tcount].j))</p>
74、<p> //用switch分支語句,用compare函數(shù)對需要相加的兩個矩陣的某元素行數(shù)列數(shù)進(jìn)行比較</p><p> {case -1: S.data[q].e=M.data[mcount].e;//當(dāng)M.data[mcount].i<T.data[tcount].i或M.data[mcount].j<T.data[tcount].j</p><p> S
75、.data[q].i=M.data[mcount].i;</p><p> S.data[q].j=M.data[mcount].j;</p><p> //把第一個矩陣的行數(shù)i,列數(shù)j賦值給S矩陣的行數(shù)i,列數(shù)j</p><p><b> q++;</b></p><p> mcount++; </p&g
76、t;<p><b> break;</b></p><p> case 1: S.data[q].e=T.data[tcount].e;//當(dāng)M.data[mcount].i>T.data[tcount].i或M.data[mcount].j>T.data[tcount].j</p><p> S.data[q].i=T.data[tc
77、ount].i;</p><p> S.data[q].j=T.data[tcount].j;</p><p> //把第二個矩陣的行數(shù)i,列數(shù)j賦值給S矩陣的行數(shù)i,列數(shù)j</p><p><b> q++;</b></p><p> tcount++; </p><p><b&g
78、t; break;</b></p><p> case 0: ce=M.data[mcount].e+T.data[tcount].e;</p><p> //其他情況下把兩個矩陣的值相加</p><p> if(ce){ S.data[q].e=ce;</p><p> S.data[q].i=M.data[mco
79、unt].i;</p><p> S.data[q].j=M.data[mcount].j;</p><p><b> q++;</b></p><p><b> mcount++;</b></p><p> tcount++;}</p><p> else {mc
80、ount++;</p><p> tcount++;}</p><p><b> break;</b></p><p><b> }}</b></p><p> while(mcount<=M.tu){</p><p> S.data[q].e=M.data[
81、mcount].e;</p><p> S.data[q].i=M.data[mcount].i;</p><p> S.data[q].j=M.data[mcount].j;</p><p><b> q++;</b></p><p> mcount++; }//在case=-1的情況下對S矩陣的非零值,行數(shù),
82、列數(shù)進(jìn)行賦值</p><p> while(tcount<=M.tu){</p><p> S.data[q].e=T.data[tcount].e;</p><p> S.data[q].i=T.data[tcount].i;</p><p> S.data[q].j=T.data[tcount].j;</p>
83、<p><b> q++;</b></p><p> tcount++; </p><p> }//在case=1的情況下對S矩陣的非零值,行數(shù),列數(shù)進(jìn)行賦值</p><p><b> S.tu=q-1;</b></p><p><b> }//三元組相加</b&
84、gt;</p><p> int SMatrix_ADD(CrossList *A,CrossList *B){</p><p> OLNode *pa,*pb,*pre,*p,*cp[100]; //定義OLNode類型的變量</p><p> int i,j,t;</p><p> t=A->tu+B->tu;<
85、/p><p> for(j=1;j<=A->nu;j++)cp[j]=A->chead[j];//將A矩陣的列表頭指針賦給cp數(shù)組</p><p> for(i=1;i<=A->mu;i++){</p><p> pa=A->rhead[i];</p><p> pb=B->rhead[i];//
86、將A,B矩陣的行表頭指針分別賦給pa,pb</p><p><b> pre=NULL;</b></p><p> while(pb){//當(dāng)pb不等于零</p><p> if(pa==NULL||pa->j>pb->j){</p><p> p=(OLink)malloc(sizeof(OL
87、Node));//給p動態(tài)分配空間</p><p> if(!pre)A->rhead[i]=p;</p><p> else pre->right=p;</p><p> p->right=pa;</p><p><b> pre=p;</b></p><p> p-
88、>i=i;p->j=pb->j;p->e=pb->e;</p><p> if(!A->chead[p->j]){</p><p> A->chead[p->j]=cp[p->j]=p;</p><p> p->down=NULL;</p><p> }//如果A-&g
89、t;chead[p->j]不等于零,則把p賦給它及cp[p->j]</p><p><b> else{</b></p><p> cp[p->j]->down=p;</p><p> cp[p->j]=p;</p><p><b> }</b></p&g
90、t;<p> pb=pb->right;</p><p> }//否則把p賦給cp[p->j]</p><p> else if(pa->j<pb->j){pre=pa;</p><p> pa=pa->right;}</p><p> else if(pa->e+pb->
91、;e){</p><p><b> t--;</b></p><p> pa->e+=pb->e;</p><p><b> pre=pa;</b></p><p> pa=pa->right;</p><p> pb=pb->right;}
92、</p><p> else { t=t-2;</p><p> if(!pre)A->rhead[i]=pa->right;</p><p> else pre->right=pa->right;</p><p> p=pa;pa=pa->right;</p><p>
93、if(A->chead[p->j]==p)A->chead[p->j]=cp[p->j]=p->down;</p><p> else cp[p->j]->down=p->down;</p><p><b> free(p);</b></p><p> pb=pb->right;
94、</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> A->mu=A->mu>B->mu?A->mu:B->mu;</p><p>
95、; A->nu=A->nu>B->nu?A->nu:B->nu;//A的行與列為A及B當(dāng)中較大的一個</p><p><b> return 1;</b></p><p><b> }//十字鏈表相加</b></p><p> (5)實現(xiàn)兩個矩陣的相乘:</p>&
96、lt;p> int MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)</p><p><b> {</b></p><p> int arow, brow, ccol, i, t, ctemp[100], p, q, tp; </p><p> //定義相乘函數(shù)中所需要用到
97、的變量</p><p> if(M.nu != N.mu) return 0;</p><p> //如果第一個矩陣的行數(shù)不等于第二個矩陣的列數(shù),則退出</p><p> Q.mu = M.mu, Q.nu = N.nu, Q.tu = 0;//三元組結(jié)構(gòu)類型Q存放相乘后的結(jié)果</p><p> if(M.tu * N.tu != 0
98、)//如果兩個矩陣元素相乘不為零,則進(jìn)行運(yùn)算</p><p><b> {</b></p><p> for(arow = 1; arow <= M.mu; ++arow);//最外側(cè)循環(huán)以矩陣行數(shù)作為循環(huán)變量</p><p><b> {</b></p><p> for(i = 0
99、; i <= N.nu; ++i) ctemp[i] = 0;</p><p> Q.rpos[arow] = Q.tu + 1;</p><p> if(arow < M.mu) tp = M.rpos[arow + 1];</p><p> else tp = M.tu +1;</p><p> for(p = M.r
100、pos[arow]; p < tp; ++p)//把每行與每列相乘</p><p><b> {</b></p><p> brow = M.data[p].j; </p><p> if(brow < N.mu) t = N.rpos[brow+1];</p><p> else t
101、= N.tu + 1;</p><p> for(q = N.rpos[brow]; q < t; ++q)</p><p><b> {</b></p><p> ccol = N.data[q].j; </p><p> ctemp[ccol] += M.data[p].e * N.data[q
102、].e;//值相乘</p><p><b> }</b></p><p><b> }</b></p><p> for(ccol = 1; ccol <= Q.nu; ++ccol) //把運(yùn)算后的結(jié)果存放到Q中</p><p><b> {</b></p
103、><p> if(ctemp[ccol])</p><p><b> {</b></p><p> if(++(Q.tu) > MAXSIZE) return 1;</p><p> Q.data[Q.tu].i = arow, Q.data[Q.tu].j = ccol, Q.data[Q.tu].e = c
104、temp[ccol]; </p><p><b> } </b></p><p><b> }</b></p><p><b> } </b></p><p><b> }</b></p><p>&l
105、t;b> return 1;</b></p><p><b> }//三元組相乘</b></p><p> int MultSMatrix_OL(CrossList M, CrossList N, CrossList &Q)</p><p><b> {</b></p>&l
106、t;p> int i, j, e; //中間變量</p><p> OLink p0, q0, p, pl, pla; //中間變量</p><p> if(M.nu != N.mu) //檢查稀疏矩陣M的列數(shù)和N的行數(shù)是否對應(yīng)相等</p><p><b> {</b>&l
107、t;/p><p> printf ( "稀疏矩陣A的列數(shù)和B的行數(shù)不相等,不能相乘。\n" );</p><p> return 0; </p><p><b> }</b></p><p> Q.mu = M.mu, Q.nu = N.nu, Q.tu = 0;</p><
108、;p> if(!(Q.rhead = (OLink *)malloc((Q.mu + 1) * sizeof(OLink)))) exit(-2);</p><p> if(!(Q.chead = (OLink *)malloc((Q.nu + 1) * sizeof(OLink)))) exit(-2);</p><p> for(i = 1; i <= Q.mu; i
109、++) Q.rhead[i] = NULL;</p><p> for(i = 1; i <= Q.nu; i++) Q.chead[i] = NULL; //相乘</p><p> for(i =1; i <= Q.mu; i++)</p><p> for(j = 1; j <= Q.nu; j++)</p><p&g
110、t;<b> {</b></p><p> p0 = M.rhead[i], q0 = N.chead[j], e = 0;</p><p> while(p0&&q0) //M第i行和N第j列有元素</p><p><b> {</b></p><p&g
111、t; if( p0->j > q0->i) q0 = q0->down;//M的列大于N的行,則N的列指針后移</p><p> else if(p0->j < q0->i) p0 = p0->right;//M的列小于N的行,則M的行指針右移</p><p> else { //M的行等于N
112、的列</p><p> e += p0->e * q0->e; //乘積累加</p><p> q0 = q0->down, p0 = p0->right; //移動指針</p><p><b> }</b></p><p><b> }</b
113、></p><p> if(e) //乘積不為零</p><p><b> {</b></p><p> if(!(p = (OLink)malloc(sizeof(OLNode)))) exit(-2);</p><p> Q.tu++
114、;//非零元素增加</p><p> p->i = i, p->j = j, p->e = e, p->right = NULL, p->down = NULL;</p><p><b> //賦值,指針后移</b></p><p> //將p插入十字鏈表</p><p><b&
115、gt; //行插入</b></p><p> if(Q.rhead[i] == NULL) //若p為該行的第個結(jié)點</p><p> Q.rhead[i] = pl = p; //p插在該行的表頭且pl指向p(該行的最后一個結(jié)點)</p><p> else pl->right = p, pl = p; //插在pl所指
116、結(jié)點之后,pl右移</p><p><b> //列插入</b></p><p> if(Q.chead[j] == NULL) //若p為該列的第一個結(jié)點</p><p> Q.chead[j] = p; //該列的表頭指向p</p><p> else {//插在
117、列表尾</p><p> pla = Q.chead[j];//pla指向j行的第個結(jié)點</p><p> while(pla->down) pla = pla->down;//pla指向j行最后一個結(jié)點</p><p> pla->down = p; </p><p><b> }</b>&l
118、t;/p><p><b> }</b></p><p><b> }</b></p><p><b> return 1;</b></p><p><b> }//十字鏈表相乘</b></p><p><b> 調(diào)試
119、分析</b></p><p> 5.1系統(tǒng)運(yùn)行主界面</p><p> 系統(tǒng)運(yùn)行主界面如圖2所示:</p><p><b> 圖2 主界面圖</b></p><p> 5.2 各子功能測試運(yùn)行結(jié)果</p><p> ?。?)稀疏矩陣的創(chuàng)建及初始化:</p><
120、;p> 在主菜單下,用戶輸入1回車,是用三元組創(chuàng)建稀疏矩陣,根據(jù)屏幕提示初始化一個稀疏矩陣,按enter鍵,運(yùn)行結(jié)果如圖3所示。</p><p> 圖3 三元組創(chuàng)建并初始化矩陣</p><p> 在主菜單下,用戶輸入2回車,是用十字鏈表創(chuàng)建稀疏矩陣,根據(jù)屏幕提示初始化</p><p> 一個稀疏矩陣,按enter鍵,運(yùn)行結(jié)果如圖4所示。</p&g
121、t;<p> 圖4 十字鏈表創(chuàng)建并初始化矩陣</p><p> (2)稀疏矩陣的轉(zhuǎn)置:</p><p> 用三元組創(chuàng)建稀疏矩陣后,用戶輸入1回車,便顯示該矩陣的轉(zhuǎn)置矩陣,運(yùn)行結(jié)果如圖5所示。</p><p> 圖5 三元組稀疏矩陣轉(zhuǎn)置結(jié)果示意圖</p><p> 用十字鏈表創(chuàng)建稀疏矩陣后,用戶輸入1回車,便顯示該矩陣的
122、轉(zhuǎn)置矩陣,運(yùn)行結(jié)果如圖6所示。</p><p> 圖6 十字鏈表稀疏矩陣轉(zhuǎn)置結(jié)果示意圖</p><p> ?。?)稀疏矩陣的相加:</p><p> 用三元組創(chuàng)建并初始化一個稀疏矩陣后,輸入2回車,按屏幕提示輸入第二個同類型的稀疏矩陣,按enter鍵,運(yùn)行結(jié)果如圖7所示。</p><p> 圖7 三元組稀疏矩陣相加結(jié)果示意圖</p
123、><p> 用十字鏈表創(chuàng)建并初始化一個稀疏矩陣后,輸入2回車,按屏幕提示輸入第二個同類型的稀疏矩陣,按enter鍵,運(yùn)行結(jié)果如圖8所示。</p><p> 圖8 三元組稀疏矩陣相加結(jié)果示意圖</p><p> ?。?)稀疏矩陣的相乘:</p><p> 用三元組創(chuàng)建并初始化一個稀疏矩陣后,輸入3回車,按屏幕提示輸入第二個同類型的稀疏矩陣,按
124、enter鍵,運(yùn)行結(jié)果如圖9所示。</p><p> 圖9 三元組稀疏矩陣相乘結(jié)果示意圖</p><p> 用十字鏈表創(chuàng)建并初始化一個稀疏矩陣后,輸入3回車,按屏幕提示輸入第二個同類型的稀疏矩陣,按enter鍵,運(yùn)行結(jié)果如圖10所示。</p><p> 圖10 十字鏈表稀疏矩陣相乘結(jié)果示意圖</p><p><b> ?。?)
125、退出:</b></p><p> 在主菜單下,用戶輸入3回車,或者在下級菜單中輸入4回車,退出程序。運(yùn)行結(jié)果如圖11,圖12。</p><p> 圖11 主菜單退出程序圖</p><p> 圖12 下級菜單退出程序圖</p><p><b> 總結(jié)</b></p><p>
126、由于本程序要求用兩種辦法對稀疏矩陣進(jìn)行運(yùn)算,特別是用十字鏈表這種形式來對稀</p><p> 疏矩陣進(jìn)行運(yùn)算,是實現(xiàn)起來有很多困難,主要包括:</p><p> 1、書上這種方面的東西不多,資料少,可以參考的東西不是很多;</p><p> 2、用十字鏈表進(jìn)行運(yùn)算比較復(fù)雜,難度較大,需要對指針掌握較好;</p><p> 3、在書寫課
127、程設(shè)計報告時,沒有具體的模板,感覺無從下手。</p><p> 針對上述困難,自己對癥下藥,通過網(wǎng)絡(luò),圖書館找資料,借鑒別人的已往的優(yōu)秀的課程設(shè)計報告,和同學(xué)們一起討論,逐步地解決自己的問題。</p><p> 通過此次課程設(shè)計,使我對本學(xué)期學(xué)的《數(shù)據(jù)結(jié)構(gòu)》有了更深的了解,也使自己的所學(xué)更加牢固,并能夠把更方面的知識綜合起來運(yùn)用。</p><p><b&g
128、t; 參考文獻(xiàn)</b></p><p> [1]王立柱.C/C++與數(shù)據(jù)結(jié)構(gòu).北京:清華大學(xué)出版社,2002</p><p> [2]顧元剛.數(shù)據(jù)結(jié)構(gòu)簡明教程.南京:東南大學(xué)出版社等,2003</p><p> [3]郭福順,王曉芬,李蓮治《數(shù)據(jù)結(jié)構(gòu)》(修訂本),大連理工大學(xué)出版社,1997</p><p> [4
129、] [美]Mark Allen Weiss,數(shù)據(jù)結(jié)構(gòu)與算法分析——C語言描述(英文版?第2版),人民郵電出版社,2005.8</p><p> [5] 李春葆著,數(shù)據(jù)結(jié)構(gòu)教程,清華大學(xué)出版社,2005.1</p><p><b> 附錄:程序源代碼</b></p><p> #include<stdio.h></p&g
130、t;<p> #include<stdlib.h></p><p> #define MAXSIZE 100</p><p> int num[100];</p><p> typedef struct OLNode{</p><p><b> int i,j;</b></p&g
131、t;<p><b> int e;</b></p><p> struct OLNode *right,*down;</p><p> }OLNode,*OLink;</p><p> typedef struct {</p><p> int mu,nu,tu;</p><p
132、> OLink *rhead,*chead;</p><p> }CrossList; //十字鏈表結(jié)構(gòu)體定義 </p><p> typedef struct{</p><p><b> int i,j;</b></p><p><b> int e;</b>&
溫馨提示
- 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---稀疏矩陣
- 數(shù)據(jù)結(jié)構(gòu)與課程設(shè)計---稀疏矩陣
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-- 稀疏矩陣的運(yùn)算
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--稀疏矩陣的操作
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--稀疏矩陣運(yùn)算器
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-稀疏矩陣實現(xiàn)與應(yīng)用
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計論文----稀疏矩陣的轉(zhuǎn)置
- 《數(shù)據(jù)結(jié)構(gòu)》課程設(shè)計報告--稀疏矩陣運(yùn)算器
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告--稀疏矩陣運(yùn)算器
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告 稀疏矩陣運(yùn)算器
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告 稀疏矩陣運(yùn)算器設(shè)計
- 稀疏矩陣的轉(zhuǎn)置論文-數(shù)據(jù)結(jié)構(gòu)課程設(shè)計論文
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--基本稀疏矩陣運(yùn)算的運(yùn)算器
- 數(shù)據(jù)結(jié)構(gòu)-矩陣相關(guān)操作的課程設(shè)計
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計--數(shù)據(jù)結(jié)構(gòu)課程設(shè)計----huffman編碼
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計-圖的鄰接矩陣
- 數(shù)據(jù)結(jié)構(gòu)實驗報告(稀疏矩陣)
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計
- 數(shù)據(jù)結(jié)構(gòu)課程設(shè)計
評論
0/150
提交評論