版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
整理為word格式整理為word格式整理為word格式《數(shù)據(jù)結(jié)構(gòu)》課程設(shè)計(jì)報(bào)告課程題目:關(guān)鍵路徑學(xué)院:班級(jí):學(xué)號(hào):姓名:指導(dǎo)教師:完成日期:目錄TOC\o"1-1"\h\z\u一、需求分析 3整理為word格式整理為word格式整理為word格式二、概要設(shè)計(jì) 4三、詳細(xì)設(shè)計(jì) 5四、 調(diào)試分析 11五、 用戶使用說明 12六、 測試結(jié)果 12七、 附錄 13一、需求分析1、問題描述整理為word格式整理為word格式整理為word格式AOE網(wǎng)(即邊表示活動(dòng)的網(wǎng)絡(luò)),在某些工程估算方面非常有用。它可以使人們了解:(1)研究某個(gè)工程至少需要多少時(shí)間?(2)哪些活動(dòng)是影響工程進(jìn)度的關(guān)鍵?在AOE網(wǎng)絡(luò)中,從源點(diǎn)到匯點(diǎn)的有向路徑可能不止一條,但只有各條路徑上所有活動(dòng)都完成了,這個(gè)工程才算完成。因此,完成整個(gè)工程所需的時(shí)間取決于從源點(diǎn)到匯點(diǎn)的最長路徑長度,即在這條路徑上所有活動(dòng)的持續(xù)時(shí)間之和,這條路徑就叫做關(guān)鍵路徑(criticalpath)。2、設(shè)計(jì)步驟(1)、以某一工程為藍(lán)本,采用圖的結(jié)構(gòu)表示實(shí)際的工程計(jì)劃時(shí)間。(2)、調(diào)查并分析和預(yù)測這個(gè)工程計(jì)劃每個(gè)階段的時(shí)間。(3)、用調(diào)查的結(jié)果建立AOE網(wǎng),并用圖的形式表示。(4)、用CreateGraphic()函數(shù)建立圖的鄰接表存儲(chǔ)結(jié)構(gòu),能夠輸入圖的頂點(diǎn)和邊的信息,并存儲(chǔ)到相應(yīng)存儲(chǔ)結(jié)構(gòu)中。(5)、用SearchMaxPath()函數(shù)求出最大路徑,并打印出關(guān)鍵路徑。(6)、編寫代碼并調(diào)試、測試通過。3、測試數(shù)據(jù)eq\o\ac(○,v2)eq\o\ac(○,v5)eq\o\ac(○,v1)eq\o\ac(○,v4)eq\o\ac(○,v6)eq\o\ac(○,v3)6v1v2v3v4v5v68v1v2a13v1v3a22v2v4a32v2v5a43v3v4a54v3v6a63v4v6a72v5v6a81整理為word格式整理為word格式整理為word格式二、 概要設(shè)計(jì)為了實(shí)現(xiàn)上述函數(shù)功能: 1、抽象數(shù)據(jù)類型圖的定義如下:ADTGraph{數(shù)據(jù)對(duì)象V:V是具有相同特性的數(shù)據(jù)元素的集合,稱為頂點(diǎn)集。數(shù)據(jù)關(guān)系R:R={VR};VR={<v,w>|v,w∈V,且P(v,w),<v,w>表示從v到w的弧,謂詞P(v,w)定義了?。紇,w>的意義和信息}基本操作:InitGraph(G);初始條件:圖G存在。操作結(jié)果:構(gòu)造一個(gè)圖的頂點(diǎn)數(shù)為MAX,弧的個(gè)數(shù)也為MAX,其他信息都相應(yīng)初始化了的圖。CreatGraph(&G);初始條件:已經(jīng)初始化了的圖G。操作結(jié)果:通過輸入函數(shù)輸入圖的頂點(diǎn)個(gè)數(shù),各頂點(diǎn)信息,弧的條數(shù),以及弧的其他信息,構(gòu)造圖G。}2、抽象數(shù)據(jù)類型棧的定義如下:ADTStack{數(shù)據(jù)對(duì)象:D={ai|ai∈ElemSet,i=1,2,…,n,n≥0}數(shù)據(jù)關(guān)系:Rl={<ai-1,ai>|ai-1,ai∈D,i=2,…,n}約定an端為棧頂,ai端為棧底?;静僮鳎篒nitStack(&S)操作結(jié)果:構(gòu)造一個(gè)空棧S。StackEmpty(S)初始條件:棧S已經(jīng)存在。操作結(jié)果:若棧S為空棧,則返回TRUE,否則FALSE。整理為word格式整理為word格式整理為word格式Push(&S,e)初始條件:棧S已經(jīng)存在。操作結(jié)果:插入元素e為新的棧頂元素。Pop(&S,&e)初始條件:棧S已存在且不為空。操作結(jié)果:刪除S的棧頂元素,并用e返回其值。}三、詳細(xì)設(shè)計(jì)1、圖的鄰接表存儲(chǔ)結(jié)構(gòu)如下:#defineMAX20typedefstructArcNode//表節(jié)點(diǎn){ intadjvex;//該弧所指向的頂點(diǎn)的位置 structArcNode*next;//指向下一條弧的指針 char*info1;//表示活動(dòng),如a1、a2、a3等等 intinfo2;//表示權(quán)值}ArcNode;typedefstructVNode//頭結(jié)點(diǎn){ Vertextypedata[3];//頂點(diǎn)信息,如v1、v2、v3等等。 ArcNode*first;//指向第一條依附該頂點(diǎn)的弧的指針。}VNode,AdjList[MAX];typedefstruct{ AdjListvertices; intvexnum;//圖的頂點(diǎn)數(shù) intarcnum;//圖的弧數(shù)}ALGraph;整理為word格式整理為word格式整理為word格式2、棧的順序存儲(chǔ)結(jié)構(gòu)如下:#defineSIZEMAX20#defineADD10typedefintElemtype;typedefstruct{ Elemtype*base; Elemtype*top; intmaxsize;}Stack;3、圖的構(gòu)建函數(shù)設(shè)計(jì)如下:intID[MAX]={0};//存放每個(gè)頂點(diǎn)的入度的數(shù)組IDintve[MAX]={0};//用來存放每個(gè)頂點(diǎn)的最早發(fā)生時(shí)間的數(shù)組vecharstr3[MAX][10];//存放活動(dòng)的字符串?dāng)?shù)組voidInitGraph(ALGraph&G)//初始化圖時(shí)將圖的頂點(diǎn)數(shù)、弧數(shù)都賦為MAX{ G.vexnum=MAX; G.arcnum=MAX; for(inti=0;i<G.vexnum;i++)//每一個(gè)頭結(jié)點(diǎn)的first指針都指向空 G.vertices[i].first=NULL;}voidCreateGraphic(ALGraph&G){ inti,j,s,n;ArcNode*p,*pp;//定義兩個(gè)指向ArcNode表結(jié)點(diǎn)的指針p,pp charstr1[10],str2[10];//定義兩個(gè)字符串str1,str2,最大長度為10 scanf("%d\n",&G.vexnum);//輸入圖的頂點(diǎn)數(shù)vexnum for(i=0;i<G.vexnum;i++) { scanf("%s",G.vertices[i].data);//輸入各頂點(diǎn)的信息,頂點(diǎn)名稱整理為word格式整理為word格式整理為word格式 G.vertices[i].first=NULL;//第i個(gè)頭結(jié)點(diǎn)的first域指向空 } scanf("%d\n",&G.arcnum);//輸入圖的弧數(shù)arcnumfor(i=0;i<G.arcnum;i++) { scanf("%s%s%s%d",str1,str2,str3[i],&n);//輸入每條弧的其它相關(guān)信息,str1是弧的弧尾,str2是弧的弧頭,str3指的是活動(dòng),n指的是權(quán)值 for(j=0;j<G.vexnum;j++)//根據(jù)str1,找對(duì)應(yīng)的弧尾,若找到, if(strcmp(str1,G.vertices[j].data)==0)則停止查找,并保存弧尾 break;所示的頂點(diǎn)在頭結(jié)點(diǎn)中的序號(hào)j for(s=0;s<G.arcnum;s++)//根據(jù)str1,找對(duì)應(yīng)的弧頭,若找到 if(strcmp(str2,G.vertices[s].data)==0)則停止查找,并保存弧頭 break;所示的頂點(diǎn)在頭結(jié)點(diǎn)中的序號(hào)s pp=(ArcNode*)malloc(sizeof(ArcNode));//給pp申請一個(gè)內(nèi)存空間 pp->adjvex=s;//將弧頭所指向的頂點(diǎn)的位置下標(biāo)存放在pp的adjvex域中 pp->info1=str3[i];//將該弧的活動(dòng)信息存放在pp的info1域中 pp->info2=n;//將該弧的權(quán)值大小存放在pp的info2域中 pp->next=NULL;//pp的next指向空 ID[s]++;//s的入度加1 if(G.vertices[j].first!=NULL)//如果序號(hào)為j的頭結(jié)點(diǎn)的first所指向的不為 {空,則表示該頂點(diǎn)已經(jīng)連好了一條弧,需要找下一個(gè)可存放的位置整理為word格式整理為word格式整理為word格式 p=G.vertices[j].first;//用一個(gè)臨時(shí)指針保存該頭結(jié)點(diǎn)的first指針 if(p->next!=NULL)//如果first所指向的表結(jié)點(diǎn)的next指向不為空, {//則需要找下一個(gè)可存放位置 while(p->next->next!=NULL)//如果p所指向的表結(jié)點(diǎn)的next {所指向另一表結(jié)點(diǎn)的next不為空,就把p指針往后移一位 p=p->next; } p=p->next; } p->next=pp;//直到p的next指向?yàn)榭眨侔裵的next指向pp } elseG.vertices[j].first=pp;//如果序號(hào)為j的頭結(jié)點(diǎn)的first所指向的為空,直接把它的first指向pp }}4、堆棧的功能函數(shù)設(shè)計(jì)如下:StatusInitStack(Stack&S)//棧的初始化操作{ S.base=(Elemtype*)malloc(SIZEMAX*sizeof(Elemtype));//給棧分配內(nèi)存空間 if(!S.base)exit(OVERFLOW);//若分配不成功,則返回OVERFLOW; S.top=S.base;//讓棧的棧頂指針和棧底指針相等 S.maxsize=SIZEMAX;//棧的當(dāng)前容量為SIZEMAX returnOK;}StatusPop(Stack&S,int&e){整理為word格式整理為word格式整理為word格式 if(S.top==S.base)//如果棧的棧頂指針等于棧底指針,則表示當(dāng)前棧為空 returnERROR;//棧頂元素不存在,所以返回ERROR e=*(--S.top);//如果棧不為空,就取出S的棧頂指針?biāo)赶虻臄?shù)據(jù), returnOK;//并把top指針往下移一個(gè)位置}StatusPush(Stack&S,inte){ if(S.top-S.base>=S.maxsize)//如果當(dāng)前棧內(nèi)存的元素超過了它的最大存放量 {//則必須追加空間 S.base=(Elemtype*)realloc(S.base,(S.maxsize+ADD)*sizeof(Elemtype)); if(!S.base) exit(OVERFLOW); S.top=S.base+S.maxsize; S.maxsize=S.maxsize+ADD; } *(S.top++)=e;//top指針往上移一位后,讓top指針指向元素e returnOK;}StatusEmpty(StackS){ if(S.top==S.base)returnOK; //如果棧的棧頂指針等于棧底指針,則表示當(dāng)前棧為空,返回OKelsereturnERROR;//否則返回ERROR}5、求關(guān)鍵路徑的函數(shù)設(shè)計(jì)如下:StatusTopo(ALGraphG,Stack&T)//拓?fù)渑判蚝瘮?shù){inti,j,k; ArcNode*p;//定義一個(gè)指向ArcNode表結(jié)點(diǎn)的指針p整理為word格式整理為word格式整理為word格式 StackS;//定義一個(gè)存放入度為0的頂點(diǎn)所在的下標(biāo)值的棧InitStack(S);//初始化棧S for(j=0;j<G.vexnum;j++)//查看各個(gè)頂點(diǎn)的入度是否為0, if(ID[j]==0)//若為0,就讓該頂點(diǎn)所在位置的下標(biāo)值入棧 Push(S,j); intcount=0;//記錄進(jìn)入拓?fù)渑判驐的元素個(gè)數(shù) while(!Empty(S)) { Pop(S,j);//從零入度頂點(diǎn)棧S中取出棧頂元素,存放在j中 Push(T,j);//元素j入棧T,表示序號(hào)為j的頂點(diǎn)入棧 count++; for(p=G.vertices[j].first;p;p=p->next) {//找以第j個(gè)頂點(diǎn)為弧尾的弧的弧頭 k=p->adjvex;//保存弧頭所示的頂點(diǎn)的位置下標(biāo) ID[k]--;//刪除該弧后,弧頭所示的頂點(diǎn)入度減1 if(ID[k]==0)Push(S,k);//如果該頂點(diǎn)入度為0,就入棧S if((ve[j]+(p->info2))>ve[k])ve[k]=ve[j]+(p->info2);//如果j號(hào)頂點(diǎn)的最早發(fā)生時(shí)間與該弧的權(quán)值之和大于k號(hào)定點(diǎn)的 }//最早發(fā)生時(shí)間,就改變k號(hào)頂點(diǎn)的最早發(fā)生時(shí)間 } if(count<G.vexnum)returnERROR;//如果拓?fù)湫蛄袟V械捻旤c(diǎn)數(shù)小于圖的頂點(diǎn)數(shù),則表示圖中有環(huán),沒有關(guān)鍵路徑 elsereturnOK;}StatusCritial(ALGraphG)//求關(guān)鍵路徑函數(shù){ inti,j,k,ee,el; intvl[MAX];//存放各頂點(diǎn)最遲發(fā)生時(shí)間的數(shù)組vlStackT;//定義一個(gè)存放拓?fù)湫蛄性氐臈整理為word格式整理為word格式整理為word格式InitStack(T);//初始化該棧ArcNode*p; if(!Topo(G,T))returnERROR;//如果拓?fù)渑判虿怀晒?,也無法找到關(guān)鍵路徑,就返回ERROR for(i=0;i<G.vexnum;i++)//頂點(diǎn)最遲發(fā)時(shí)間始化,都等于最后一個(gè)頂點(diǎn)的ve vl[i]=ve[G.vexnum-1]; while(!Empty(T))//在入度頂點(diǎn)棧不為空的條件下循環(huán) { for(Pop(T,j),p=G.vertices[j].first;p;p=p->next) {//取出棧頂元素,并查找以j號(hào)頂點(diǎn)為弧尾的弧的弧頭 k=p->adjvex;//把弧頭所示的頂點(diǎn)位置下標(biāo)值存放在k中 if(vl[k]-(p->info2)<vl[j])vl[j]=vl[k]-(p->info2);//如果k號(hào)頂點(diǎn)的最遲發(fā)生時(shí)間與該弧的權(quán)值之差小于j號(hào)定點(diǎn)的最遲發(fā)生時(shí)間,就改變vl[j] } } printf("關(guān)鍵頂點(diǎn)為a:"); for(j=0;j<G.vexnum;j++) {if(ve[j]==vl[j])//如果定點(diǎn)的最早發(fā)生時(shí)間與最遲發(fā)生時(shí)間相等,則表示該 printf("%s",G.vertices[j].data);//頂點(diǎn)是關(guān)鍵頂點(diǎn),就輸出該關(guān)鍵頂點(diǎn)的名稱 } printf("\n"); printf("關(guān)鍵路徑為:"); for(j=0;j<G.vexnum;j++) { for(p=G.vertices[j].first;p;p=p->next)整理為word格式整理為word格式整理為word格式 {k=p->adjvex; ee=ve[j]; el=vl[k]-(p->info2); if(el==ee)printf("%s",p->info1); } } printf("\n"); returnOK;}四、 調(diào)試分析1、本次課程設(shè)計(jì)題目思路特別清晰,算法特別簡單,但是在編程過程中遇到了一系列的問題都值得思考與分析。2、首先是在圖的創(chuàng)建過程中,用鄰接表創(chuàng)建圖的時(shí)候,指針使用沒有正確到位而引發(fā)了一系列問題,后來通過與老師同學(xué)一起分析才找到了問題的癥結(jié)所在。之前用臨時(shí)指針p保存頭結(jié)點(diǎn)的first指針,然后讓p指向已經(jīng)存好信息的表結(jié)點(diǎn)pp,這樣操作并沒有真正把它連起來,下次循環(huán)時(shí),又覆蓋了原來的信息。3、在成功創(chuàng)建了圖后,把主函數(shù)中生成的圖作為參數(shù)傳給Critial()時(shí),又發(fā)現(xiàn)原來圖中的活動(dòng)這一信息又改變了,全變成亂碼了,原來是由于存放活動(dòng)的字符串str3,由于不斷的輸入,導(dǎo)致最后字符串什么也沒有了,而圖中每個(gè)弧的活動(dòng)指針都指向它,所以就全亂了,后來就把它改為字符串?dāng)?shù)組,并且把它設(shè)為全局變量。4、在調(diào)試Critial()這一函數(shù)中,也遇到了一些問題,在觀察零入度棧S的棧頂元素和拓?fù)湫蛄袟的時(shí)候,在watch窗口中輸入*(S.top--),發(fā)現(xiàn)一直亂變,根本不知道它的棧內(nèi)元素,甚至懷疑棧的初始化函數(shù)有沒有寫對(duì),后來通過查找以前堆棧類型問題以及與同學(xué)題目作對(duì)比才發(fā)現(xiàn)就是由于窗口輸入內(nèi)容寫錯(cuò)了,應(yīng)該改為*(S.top-1)。整理為word格式整理為word格式整理為word格式五、 用戶使用說明第一行輸入頂點(diǎn)個(gè)數(shù)vexnum。第二行輸入各個(gè)頂點(diǎn)的名稱。第三行輸入弧的邊數(shù)arcnum。接下來的arcnum行輸入每一條弧的弧尾頂點(diǎn)、弧頭頂點(diǎn)、活動(dòng)以及權(quán)值大小。六、 測試結(jié)果
七、 附錄
以下是該程序設(shè)計(jì)的完整代碼:#include<stdio.h>#include<string.h>#include<stdlib.h>#defineTRUE1#defineFALSE0整理為word格式整理為word格式整理為word格式#defineOK1#defineERROR0#defineOVERFLOW-2#defineMAX20#defineSIZEMAX20#defineADD10typedefintStatus;typedefintInfotype;typedefcharVertextype;typedefintElemtype;intID[MAX]={0};intve[MAX]={0};charstr3[MAX][10];typedefstructArcNode{ intadjvex; structArcNode*next; char*info1; intinfo2;}ArcNode;typedefstructVNode{ Vertextypedata[3];ArcNode*first;}VNode,AdjList[MAX];typedefstruct{ AdjListvertices; intvexnum; intarcnum;}ALGraph;typedefstruct{ Elemtype*base; Elemtype*top; intmaxsize;}Stack;voidInit(ALGraph&G){ G.vexnum=MAX;G.arcnum=MAX; for(inti=0;i<G.vexnum;i++) G.vertices[i].first=NULL;}整理為word格式整理為word格式整理為word格式voidCreateGraphic(ALGraph&G){ inti,j,s,n;ArcNode*p,*pp; charstr1[10],str2[10]; scanf("%d\n",&G.vexnum); for(i=0;i<G.vexnum;i++) { scanf("%s",G.vertices[i].data); G.vertices[i].first=NULL; } scanf("%d\n",&G.arcnum); for(i=0;i<G.arcnum;i++) { scanf("%s%s%s%d",str1,str2,str3[i],&n); for(j=0;j<G.vexnum;j++) if(strcmp(str1,G.vertices[j].data)==0) break; for(s=0;s<G.arcnum;s++) if(strcmp(str2,G.vertices[s].data)==0) break; pp=(ArcNode*)malloc(sizeof(ArcNode)); pp->adjvex=s; pp->info1=str3[i]; pp->info2=n; pp->next=NULL; ID[s]++; if(G.vertices[j].first!=NULL) { p=G.vertices[j].first; if(p->next!=NULL) { while(p->next->next!=NULL) { p=p->next; } p=p->next; } p->next=pp; } else G.vertices[j].first=pp; }}整理為word格式整理為word格式整理為word格式StatusInitStack(Stack&S){ S.base=(Elemtype*)malloc(SIZEMAX*sizeof(Elemtype)); if(!S.base)exit(OVERFLOW); S.top=S.base; S.maxsize=SIZEMAX; returnOK;}StatusPop(Stack&S,int&e){ if(S.top==S.base)returnERROR; e=*(--S.top); returnOK;}StatusPush(Stack&S,inte){ if(S.top-S.base>=S.maxsize) { S.base=(Elemtype*)realloc(S.base,(S.maxsize+add)*sizeof(Elemtype)); if(!S.base)exit(OVERFLOW); S.top=S.base+S.maxsize; S.maxsize=S.maxsize+add; } *(S.top++)=e;//*(S.top)=e,S.top++; returnOK;}StatusEmpty(StackS){ if(S.top==S.base)returnOK; elsereturnERROR;}StatusTopo(ALGraphG,Stack&T){inti,j,k; ArcNode*p; StackS;InitStack(S); for(j=0;j<G.vexnum;j++) if(ID[j]==0) Push(S,j); intcount=0; while(!Empty(S))整理為word
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度IT行業(yè)核心技術(shù)人員保密協(xié)議范本3篇
- 2025年度餐飲企業(yè)食品安全責(zé)任書6篇
- 2024限定版道路救援拖車服務(wù)合同版
- 2025年華東師大版七年級(jí)歷史下冊階段測試試卷
- 2025年人教版必修1物理下冊月考試卷含答案
- 2025年冀教版九年級(jí)科學(xué)下冊階段測試試卷
- 2025年粵教版四年級(jí)語文下冊階段測試試卷
- 2025年度房地產(chǎn)項(xiàng)目投資信息保密協(xié)議3篇
- 2025年外研版二年級(jí)數(shù)學(xué)下冊階段測試試卷含答案
- 新生兒心律失常護(hù)理診斷
- Unit 3 We should obey the rules. Lesson15(說課稿)-2023-2024學(xué)年人教精通版英語五年級(jí)下冊
- 綿陽市高中2022級(jí)(2025屆)高三第二次診斷性考試(二診)語文試卷(含答案)
- 人力資源許可證制度(服務(wù)流程、服務(wù)協(xié)議、收費(fèi)標(biāo)準(zhǔn)、信息發(fā)布審查和投訴處理)
- 借條的正規(guī)模板(2024版)
- 建設(shè)工程監(jiān)理費(fèi)計(jì)算器(免費(fèi))
- 地下連續(xù)墻拆除方案
- 二年級(jí)上冊數(shù)學(xué)期中試卷
- 工廠供配電技術(shù)習(xí)題
- 春節(jié)期間安全管理實(shí)施方案與春節(jié)期間施工現(xiàn)場維穩(wěn)方案匯編
- 建材公司財(cái)務(wù)管理制度
- 作業(yè)布置批改檢查量化評(píng)分細(xì)則(完整版)
評(píng)論
0/150
提交評(píng)論