最小生成樹和最短路徑 數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)_第1頁
最小生成樹和最短路徑 數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)_第2頁
最小生成樹和最短路徑 數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)_第3頁
最小生成樹和最短路徑 數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)_第4頁
最小生成樹和最短路徑 數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、實(shí)驗(yàn)報(bào)告六月 182015姓名:陳斌 學(xué)號:E11314079 專業(yè):13計(jì)算機(jī)科學(xué)與技術(shù)數(shù)據(jù)結(jié)構(gòu) 第八次實(shí)驗(yàn)學(xué)號 E11314079 專業(yè) 計(jì)算機(jī)科學(xué)與技術(shù) 姓名 陳 斌 實(shí)驗(yàn)日期 2015.06.18 教師簽字 成績 實(shí) 驗(yàn) 報(bào) 告【實(shí)驗(yàn)名稱】 最小生成樹和最短路徑 【實(shí)驗(yàn)?zāi)康摹?(1) 掌握最小生成樹以及最短路徑的相關(guān)概念;(2) 掌握Prim算法和Kruskal算法;(3) 掌握Dijkstra算法【實(shí)驗(yàn)內(nèi)容】l 采用普里姆算法求最小生成樹(1) 編寫一個(gè)算法,對于教材圖7.16(a)所示的無向帶權(quán)圖G采用普里姆算法輸出從頂點(diǎn)V1出發(fā)的最小生成樹。圖的存儲結(jié)構(gòu)自選。(2) 對于上圖,采

2、用克魯斯卡爾算法輸出該圖的最小生成樹。(提示:a.先對邊按權(quán)值從小到大排序,得有序邊集E;為所有頂點(diǎn)輔設(shè)一個(gè)數(shù)組Vset,標(biāo)記各頂點(diǎn)所處的連通分量,初始時(shí)各不相同。b. 依次從E中取出一條邊(i,j),檢查頂點(diǎn)i和j是否屬于同一連通分量,如是,則重取下一條邊;否則,該邊即為生成樹的一條邊,輸出該邊,同時(shí)將所有與j處于同一連通分量的頂點(diǎn)的Vset值都修改為與i的相同。c.重復(fù)b步直至輸出n-1條邊。)源代碼:head.h: #include<string.h>#include<ctype.h>#include<malloc.h> /malloc( )#incl

3、ude<limits.h> / INT ,MAX#include<stdio.h> /EOF,NULL#include<stdlib.h> /atoi( )#include<io.h> /eof( )#include<math.h> /floor( ),ceil( ),abs( )#include<process.h> /exit( )#include<iostream.h> /cout,cin/函數(shù)結(jié)果狀態(tài)代碼#define TRUE 1#define FALSE 0#define OK 1#define E

4、RROR 0#define INFEASIBLE -1/OVERFLOW 在 math.h 中已定義為3typedef int Status;typedef int Boolean; / 布爾類型main.cpp:#include"head.h"typedef int VRType;typedef char InfoType;#define MAX_NAME 3 /* 頂點(diǎn)字符串的最大長度+1 */#define MAX_INFO 20 /* 相關(guān)信息字符串的最大長度+1 */typedef char VertexTypeMAX_NAME;/*圖的數(shù)組(鄰接矩陣)存儲表示

5、*/#define INFINITY INT_MAX /* 用整型最大值代替 */#define MAX_VERTEX_NUM 20 /* 最大頂點(diǎn)個(gè)數(shù) */typedef enumDG,DN,AG,ANGraphKind; /* 有向圖,有向網(wǎng),無向圖,無向網(wǎng) */typedef structVRType adj; /* 頂點(diǎn)關(guān)系類型。對無權(quán)圖,用1(是)或0(否)表示相鄰否; */* 對帶權(quán)圖,c則為權(quán)值類型 */InfoType *info; /* 該弧相關(guān)信息的指針(可無) */ArcCell,AdjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;typedef

6、structVertexType vexsMAX_VERTEX_NUM; /* 頂點(diǎn)向量 */AdjMatrix arcs; /* 鄰接矩陣 */int vexnum,arcnum; /* 圖的當(dāng)前頂點(diǎn)數(shù)和弧數(shù) */GraphKind kind; /* 圖的種類標(biāo)志 */MGraph; int LocateVex(MGraph G,VertexType u) /* 初始條件:圖G存在,u和G中頂點(diǎn)有相同特征 */ /* 操作結(jié)果:若G中存在頂點(diǎn)u,則返回該頂點(diǎn)在圖中位置;否則返回-1 */ int i; for(i=0;i<G.vexnum;+i) if(strcmp(u,G.vexsi

7、)=0) return i; return -1; Status CreateAN(MGraph &G) /* 采用數(shù)組(鄰接矩陣)表示法,構(gòu)造無向網(wǎng)G*/ int i,j,k,w; VertexType va,vb; printf("請輸入無向網(wǎng)G的頂點(diǎn)數(shù) 邊數(shù)(用逗號隔開):"); scanf("%d,%d",&G.vexnum,&G.arcnum); printf("請輸入%d個(gè)頂點(diǎn)的值(<%d個(gè)字符;用空格隔開):n",G.vexnum,MAX_NAME); for(i=0;i<G.vexn

8、um;+i) /* 構(gòu)造頂點(diǎn)向量 */ scanf("%s",G.vexsi); for(i=0;i<G.vexnum;+i) /* 初始化鄰接矩陣 */ for(j=0;j<G.vexnum;+j) G.arcsij.adj=INFINITY; /* 網(wǎng) */ printf("請輸入%d條邊的頂點(diǎn)1 頂點(diǎn)2 權(quán)值(用空格隔開): n",G.arcnum); for(k=0;k<G.arcnum;+k) scanf("%s%s%d%*c",va,vb,&w); /* %*c吃掉回車符 */ i=LocateV

9、ex(G,va); j=LocateVex(G,vb); G.arcsij.adj=G.arcsji.adj=w; /* 無向 */ G.kind=AN; return OK; typedef struct /* 記錄從頂點(diǎn)集U到V-U的代價(jià)最小的邊的輔助數(shù)組定義 */ VertexType adjvex; VRType lowcost; minsideMAX_VERTEX_NUM; int minimum(minside SZ,MGraph G) /* 求closedge.lowcost的最小正值 */ int i=0,j,k,min; while(!SZi.lowcost) i+; min

10、=SZi.lowcost; /* 第一個(gè)不為0的值 */ k=i; for(j=i+1;j<G.vexnum;j+) if(SZj.lowcost>0) if(min>SZj.lowcost) min=SZj.lowcost; k=j; return k; void MiniSpanTree_PRIM(MGraph G,VertexType u) /* 用普里姆算法從第u個(gè)頂點(diǎn)出發(fā)構(gòu)造網(wǎng)G的最小生成樹T,輸出T的各條邊 算法7.9 */ int i,j,k; minside closedge; k=LocateVex(G,u); for(j=0;j<G.vexnum;+

11、j) /* 輔助數(shù)組初始化 */ if(j!=k) strcpy(closedgej.adjvex,u); closedgej.lowcost=G.arcskj.adj; closedgek.lowcost=0; /* 初始,U=u */ printf("最小代價(jià)生成樹的各條邊為:n"); for(i=1;i<G.vexnum;+i) /* 選擇其余G.vexnum-1個(gè)頂點(diǎn) */ k=minimum(closedge,G); /* 求出T的下一個(gè)結(jié)點(diǎn):第K頂點(diǎn) */ printf("(%s-%s)n",closedgek.adjvex,G.vex

12、sk); /* 輸出生成樹的邊 */ closedgek.lowcost=0; /* 第K頂點(diǎn)并入U(xiǎn)集 */ for(j=0;j<G.vexnum;+j) if(G.arcskj.adj<closedgej.lowcost) /* 新頂點(diǎn)并入U(xiǎn)集后重新選擇最小邊 */ strcpy(closedgej.adjvex,G.vexsk); closedgej.lowcost=G.arcskj.adj; typedef struct node int va; /邊的起始頂點(diǎn) int vb; /邊的終止頂點(diǎn) int w; /邊的權(quán)值 Edge;int VsetMAX_VERTEX_NUM;

13、void Initialize(MGraph &G)for(int i=0;i<G.vexnum;i+)Vseti = i;int Sizearray(MGraph G) return 2*G.arcnum-1;void Switch(Edge &b,Edge a) b.va=a.va; b.vb=a.vb; b.w=a.w;void HeapAdjust(Edge a,int low,int high)/建大頂堆int i=low;Edge temp;Switch(temp,ai); /先將堆頂存入tempfor(int j=2*i+1;j<=high;j=2*j

14、+1) if(j<high && aj.w<aj+1.w)/找到其最大的兒子 j+; if(temp.w<aj.w) /若不滿足大頂堆條件,則需進(jìn)行調(diào)準(zhǔn) Switch(ai,aj); i=j; else break;Switch(ai,temp); /最后確定ai的位置void Heapsort(Edge a,MGraph G)Edge temp;for(int i=Sizearray(G)/2;i>=0;-i)HeapAdjust(a,i,Sizearray(G);for(i=Sizearray(G);i>0;-i)Switch(temp,a0)

15、;Switch(a0,ai);Switch(ai,temp);HeapAdjust(a,0,i-1);void MiniSpanTree_Kruskal(MGraph G)Edge EMAX_VERTEX_NUM;int k=0;for (int i=0;i<G.vexnum;i+) for (int j=0;j<G.vexnum;j+) if (G.arcsij.adj!=INFINITY) Ek.va=i; Ek.vb=j; Ek.w=G.arcsij.adj; k+; Heapsort(E,G);Initialize(G); /初始化輔助數(shù)組 k=1; /生成的邊數(shù),最后要剛

16、好為總邊數(shù) int j=0; /E中的下標(biāo) printf("最小代價(jià)生成樹的各條邊及相應(yīng)權(quán)值為:n"); while (k<G.vexnum) int sn1=VsetEj.va; int sn2=VsetEj.vb; /得到兩頂點(diǎn)屬于的集合編號 if (sn1!=sn2) /不在同一集合編號內(nèi)的話,把邊加入最小生成樹 printf("(%s-%s):%dn",G.vexsEj.va,G.vexsEj.vb,Ej.w); k+; for (i=0;i<G.vexnum;i+) if (Vseti=sn2) Vseti=sn1; j+; voi

17、d main() MGraph G;CreateAN(G);cout<<"-普里姆算法輸出從頂點(diǎn)V1出發(fā)的最小生成樹-n"<<endl;MiniSpanTree_PRIM(G,G.vexs0);cout<<"-n"<<endl;cout<<"-克魯斯卡爾算法輸出從頂點(diǎn)V1出發(fā)的最小生成樹-n"<<endl;MiniSpanTree_Kruskal(G);cout<<"-"<<endl; 運(yùn)行結(jié)果: l 采用迪杰斯特拉算法

18、求單源最短路徑ecgfadb152125 431086 94編寫一個(gè)算法,采用迪杰斯特拉算法,輸出如下圖所示的有向帶權(quán)圖G中從頂點(diǎn)a到其他各頂點(diǎn)的最短路徑長度和最短路徑。圖的存儲結(jié)構(gòu)自選。源代碼:head.h: #include<string.h>#include<ctype.h>#include<malloc.h> /malloc( )#include<limits.h> / INT ,MAX#include<stdio.h> /EOF,NULL#include<stdlib.h> /atoi( )#include<

19、;io.h> /eof( )#include<math.h> /floor( ),ceil( ),abs( )#include<process.h> /exit( )#include<iostream.h> /cout,cin/函數(shù)結(jié)果狀態(tài)代碼#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1/OVERFLOW 在 math.h 中已定義為3typedef int Status;typedef int Boolean; / 布爾類型main.cpp:

20、#include"head.h"#define MAX_NAME 5 /* 頂點(diǎn)字符串的最大長度+1 */#define MAX_INFO 20 /* 相關(guān)信息字符串的最大長度+1 */typedef int VRType;typedef char InfoType;typedef char VertexTypeMAX_NAME;/*圖的數(shù)組(鄰接矩陣)存儲表示 */#define INFINITY INT_MAX /* 用整型最大值代替 */#define MAX_VERTEX_NUM 20 /* 最大頂點(diǎn)個(gè)數(shù) */typedef enumDG,DN,AG,ANGraph

21、Kind; /* 有向圖,有向網(wǎng),無向圖,無向網(wǎng) */typedef structVRType adj; /* 頂點(diǎn)關(guān)系類型。對無權(quán)圖,用1(是)或0(否)表示相鄰否; */* 對帶權(quán)圖,c則為權(quán)值類型 */InfoType *info; /* 該弧相關(guān)信息的指針(可無) */ArcCell,AdjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;typedef structVertexType vexsMAX_VERTEX_NUM; /* 頂點(diǎn)向量 */AdjMatrix arcs; /* 鄰接矩陣 */int vexnum,arcnum; /* 圖的當(dāng)前頂點(diǎn)數(shù)和弧數(shù) *

22、/GraphKind kind; /* 圖的種類標(biāo)志 */MGraph;typedef int PathMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;typedef int ShortPathTableMAX_VERTEX_NUM; int LocateVex(MGraph G,VertexType u) /* 初始條件:圖G存在,u和G中頂點(diǎn)有相同特征 */ /* 操作結(jié)果:若G中存在頂點(diǎn)u,則返回該頂點(diǎn)在圖中位置;否則返回-1 */ int i; for(i=0;i<G.vexnum;+i) if(strcmp(u,G.vexsi)=0) return i;

23、return -1; Status CreateDN(MGraph *G) /* 采用數(shù)組(鄰接矩陣)表示法,構(gòu)造有向網(wǎng)G */ int i,j,k,w; VertexType va,vb; printf("請輸入有向網(wǎng)G的頂點(diǎn)數(shù),弧數(shù): "); scanf("%d,%d",&(*G).vexnum,&(*G).arcnum); printf("請輸入%d個(gè)頂點(diǎn)的值(<%d個(gè)字符):n",(*G).vexnum,MAX_NAME); for(i=0;i<(*G).vexnum;+i) /* 構(gòu)造頂點(diǎn)向量 *

24、/ scanf("%s",(*G).vexsi); for(i=0;i<(*G).vexnum;+i) /* 初始化鄰接矩陣 */ for(j=0;j<(*G).vexnum;+j) (*G).arcsij.adj=INFINITY; /* 網(wǎng) */ printf("請輸入%d條弧的弧尾 弧頭 權(quán)值(以空格作為間隔): n",(*G).arcnum); for(k=0;k<(*G).arcnum;+k) scanf("%s%s%d%*c",va,vb,&w); /* %*c吃掉回車符 */ i=LocateV

25、ex(*G,va); j=LocateVex(*G,vb); (*G).arcsij.adj=w; /* 有向網(wǎng) */ (*G).kind=DN; return OK; typedef int QElemType; /*單鏈隊(duì)列隊(duì)列的鏈?zhǔn)酱鎯Y(jié)構(gòu) */ typedef struct QNode QElemType data; struct QNode *next; QNode,*QueuePtr; typedef struct QueuePtr front,rear; /* 隊(duì)頭、隊(duì)尾指針 */ LinkQueue; LinkQueue Q; Status InitQueue(LinkQueu

26、e *Q) /* 構(gòu)造一個(gè)空隊(duì)列Q */ (*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode); if(!(*Q).front) exit(OVERFLOW); (*Q).front->next=NULL; return OK; Status QueueEmpty(LinkQueue Q) /* 若Q為空隊(duì)列,則返回TRUE,否則返回FALSE */ if(Q.front=Q.rear) return TRUE; else return FALSE; Status EnQueue(LinkQueue *Q,QElemType e) /*

27、插入元素e為Q的新的隊(duì)尾元素 */ QueuePtr p=(QueuePtr)malloc(sizeof(QNode); if(!p) /* 存儲分配失敗 */ exit(OVERFLOW); p->data=e; p->next=NULL; (*Q).rear->next=p; (*Q).rear=p; return OK; Status DeQueue(LinkQueue *Q,QElemType *e) /* 若隊(duì)列不空,刪除Q的隊(duì)頭元素,用e返回其值,并返回OK,否則返回ERROR */ QueuePtr p; if(*Q).front=(*Q).rear) retu

28、rn ERROR; p=(*Q).front->next; *e=p->data; (*Q).front->next=p->next; if(*Q).rear=p) (*Q).rear=(*Q).front; free(p); return OK; void ShortestPath_DIJ(MGraph G,int v0,PathMatrix *P,ShortPathTable *D) /* 用Dijkstra算法求有向網(wǎng)G的v0頂點(diǎn)到其余頂點(diǎn)v的最短路徑Pv及帶權(quán)長度 */ /* Dv。若Pvw為TRUE,則w是從v0到v當(dāng)前求得最短路徑上的頂點(diǎn)。 */ /* fi

29、nalv為TRUE當(dāng)且僅當(dāng)vS,即已經(jīng)求得從v0到v的最短路徑 算法7.15 */ int v,w,i,j,min; Status finalMAX_VERTEX_NUM; for(v=0;v<G.vexnum;+v) finalv=FALSE; (*D)v=G.arcsv0v.adj; for(w=0;w<G.vexnum;+w) (*P)vw=FALSE; /* 設(shè)空路徑 */ if(*D)v<INFINITY) (*P)vv0=TRUE; (*P)vv=TRUE; (*D)v0=0; finalv0=TRUE; /* 初始化,v0頂點(diǎn)屬于S集 */ for(i=1;i&

30、lt;G.vexnum;+i) /* 其余G.vexnum-1個(gè)頂點(diǎn) */ /* 開始主循環(huán),每次求得v0到某個(gè)v頂點(diǎn)的最短路徑,并加v到S集 */ min=INFINITY; /* 當(dāng)前所知離v0頂點(diǎn)的最近距離 */ for(w=0;w<G.vexnum;+w) if(!finalw) /* w頂點(diǎn)在V-S中 */ if(*D)w<min) v=w; min=(*D)w; /* w頂點(diǎn)離v0頂點(diǎn)更近 */ finalv=TRUE; /* 離v0頂點(diǎn)最近的v加入S集 */ EnQueue(&Q,v); for(w=0;w<G.vexnum;+w) /* 更新當(dāng)前最短路

31、徑及距離 */ if(!finalw&&min<INFINITY&&G.arcsvw.adj<INFINITY&&(min+G.arcsvw.adj<(*D)w) /* 修改Dw和Pw,wV-S */ (*D)w=min+G.arcsvw.adj; for(j=0;j<G.vexnum;+j) (*P)wj=(*P)vj; (*P)ww=TRUE; void main() InitQueue(&Q); int i,j,e,v0=0; /* v0為源點(diǎn) */ MGraph g; PathMatrix p; ShortPathTable d; CreateDN(&g); ShortestPath_DIJ(g,v0,&p,&d); printf("最短路徑數(shù)組pij如下:n"); for(i=0;i<g.vexnum;+i) for(j=0;j<g.vexnum;+j) printf("%2d",pij); printf("n"); p

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論