數(shù)據(jù)結(jié)構(gòu)課程設(shè)計---稀疏矩陣_第1頁
已閱讀1頁,還剩33頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論