版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
##大學(xué)
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計報告
題目:圖的遍歷和生成樹求解
院(系):計算機工程學(xué)院
學(xué)生姓名:_____________________
班級:學(xué)號:
起迄日期:2011
指導(dǎo)教師:______________________
指導(dǎo)教師評語:成績:
簽名:
年月日
2010—2011年度第2學(xué)期
一、需求分析
1.問題描述:
圖的遍歷和生成樹求解實現(xiàn)
圖是一種較線性表和樹更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。在線性表中,數(shù)據(jù)元素之間僅
有線性關(guān)系,每個數(shù)據(jù)元素只有一個直接前驅(qū)和一個直接后繼;在樹形結(jié)構(gòu)中,
數(shù)據(jù)元素之間有著明顯的層次關(guān)系,并且每一層上的數(shù)據(jù)元素可能和下一層中多
個元素(及其孩子結(jié)點)相關(guān)但只能和上一層中一個元素(即雙親結(jié)點)相關(guān);
而在圖形結(jié)構(gòu)中,節(jié)點之間的關(guān)系可以是任意的,圖中任意兩個數(shù)據(jù)元素之間都
可能相關(guān)。
生成樹求解主要利用普利姆和克雷斯特算法求解最小生成樹,只有強連通圖
才有生成樹。
2.基本功能
1)先任意創(chuàng)建一個圖;
2)圖的DFS,BFS的遞歸和非遞歸算法的實現(xiàn)
3)最小生成樹(兩個算法)的實現(xiàn),求連通分量的實現(xiàn)
4)要求用鄰接矩陣、鄰接表等多種結(jié)構(gòu)存儲實現(xiàn)
3.輸入輸出
輸入數(shù)據(jù)類型為整型和字符型,輸出為整型和字符
二、概要設(shè)計
1.設(shè)計思路:
a.圖的鄰接矩陣存儲:根據(jù)所建無向圖的結(jié)點數(shù)n,建立n*n的矩陣,其中
元素全是無窮大(intjnax),再將邊的信息存到數(shù)組中。其中無權(quán)圖的邊用1
表示,無邊用0表示;有全圖的邊為權(quán)值表示,無邊用8表示。
b.圖的鄰接表存儲:將信息通過鄰接矩陣轉(zhuǎn)換到鄰接表中,即將鄰接矩陣的
每一行都轉(zhuǎn)成鏈表的形式將有邊的結(jié)點進行存儲。
c.圖的廣度優(yōu)先遍歷:假設(shè)從圖中的某個頂點v出發(fā),在訪問了v之后依次
訪問v的各個未曾訪問過的鄰接點,然后再訪問此鄰接點的未被訪問的鄰接點,
并使“先被訪問的頂點的鄰接點”先于“后被訪問的頂點的鄰接點”被訪問,直
至圖中所有已被訪問的頂點的鄰接點都被訪問到。若此時圖中還有未被訪問的,
則另選未被訪問的重復(fù)以上步驟,是一個非遞歸過程。
d.圖的深度優(yōu)先遍歷:假設(shè)從圖中某頂點v出發(fā),依依次訪問v的鄰接頂點,
然后再繼續(xù)訪問這個鄰接點的系一個鄰接點,如此重復(fù),直至所有的點都被訪問,
這是個遞歸的過程。
e.圖的連通分量:這是對一個非強連通圖的遍歷,從多個結(jié)點出發(fā)進行搜索,
而每一次從一個新的起始點出發(fā)進行搜索過程中得到的頂點訪問序列恰為其連
通分量的頂點集。本程序利用的圖的深度優(yōu)先遍歷算法。
2.數(shù)據(jù)結(jié)構(gòu)設(shè)計:
ADTQueue{
數(shù)據(jù)對象:D={aJa(GElemSet,i=l,2,3...,n,n20}
數(shù)據(jù)關(guān)系:Rl={<ai-bai>|alba.ED,i=l,2,3,....,n}
基本操作:
InitQueue(&Q)
操作結(jié)果:構(gòu)造一個空隊列Q。
QueueEmpty(Q)
初始條件:Q為非空隊列。
操作結(jié)果:若Q為空隊列,則返回真,否則為假。
EnQueue(&Q,e)
初始條件:Q為非空隊列。
操作結(jié)果:插入元素e為Q的新的隊尾元素。
DeQueue(&Q,e)
初始條件:Q為非空隊列。
操作結(jié)果:刪除Q的隊頭元素,并用e返回其值。
}ADTQueue
ADTGraph{
數(shù)據(jù)對象V:V是具有相同特性的數(shù)據(jù)元素的集合,稱為頂點集。
數(shù)據(jù)關(guān)系R:
R={VR}
VR={〈v,W>IV,wev且P(v,w),〈V,W〉表示從V到w的弧,
謂詞P(v.w)定義了?。紇,w>的意義或信息}
基本操作P:
CreatGraph(&G,V,VR);
初始條件:V是圖的頂點集,VR是圖中弧的集合。
操作結(jié)果:按V和VR的定義構(gòu)造圖G。
BFSTraverse(G,visit());
初始條件:圖G存在,Visit是定點的應(yīng)用函數(shù)。
操作結(jié)果:對圖進行廣度優(yōu)先遍歷。在遍歷過程中對每個頂點
調(diào)用函數(shù)Visit一次且僅一次。一旦visit()失
敗,則操作失敗。
DFSTraverse(G,visit());
初始條件:圖G存在,Visit是定點的應(yīng)用函數(shù)。
操作結(jié)果:對圖進行廣度優(yōu)先遍歷。在遍歷過程中對每個頂點
調(diào)用函數(shù)Visit一次且僅一次。一旦visit()失
敗,則操作失敗。
DFStra_fen(G)
初始條件:圖G存在,存在圖的深度優(yōu)先遍歷算法。
操作結(jié)果:從多個頂點對圖進行深度優(yōu)先遍歷,得到連通分量。
}ADTGraph;
3.軟件結(jié)構(gòu)設(shè)計:
creatMGraph_L(G)int
creatadj(gra,G)int
Ijjzprint(G)void
adjprint(gra,G)void
BFSTraverse(gra)void
DFStra(gra)int
DFSTraverse_fen(gra)int
MiniSpanTree_PRIM(g,G.vexnum)int
MiniSpanTREE_KRUSCAL(G,gra)void
三、詳細設(shè)計
1.定義程序中所有用到的數(shù)據(jù)及其數(shù)據(jù)結(jié)構(gòu),及其基本操作的實現(xiàn);
鄰接矩陣定義:
typedefstructArcCell
(
VRTypeadj;〃VRType是頂點關(guān)系類型。對無權(quán)圖,用1或0表示相鄰否;
對帶權(quán)圖,則為權(quán)值類型
InfoType*info;〃該弧相關(guān)信息的指針
}ArcCell,AdjMatrix[max][max];
typedefstruct
(
VertexTypevexs[max];〃頂點向量
AdjMatrixarcs;〃鄰接矩陣
intvexnum,arcnum;〃圖的當前頂點數(shù)和弧數(shù)
}MGraph_L;
鄰接表的定義:
typedefstructArcNode〃弧結(jié)點
{
intadjvex;〃該弧指向的頂點的位置
structArcNode*nextarc;〃指向下一條弧的指針
InfoType*info;〃該弧相關(guān)信息的指針
}ArcNode;
typedefstructVNode〃鄰接鏈表頂點頭接點
(
VertexTypedata;〃頂點信息
ArcNode*firstarc;〃指向第一條依附該頂點的弧的指針
}VNode,AdjList;
typedefstruct〃圖的定義
AdjListvertices[max];
intvexnum,arcnum;〃圖的當前頂點數(shù)和弧數(shù)
}ALGraph;
隊列定義:
typedefstructQNode
(
QElemTypedata;
structQNode*next;
}QNode,*QueuePtr;
typedefstruct
(
QueuePtrfront;〃隊頭指針
QueuePtrrear;〃隊尾指針
}LinkQueue;
2.主函數(shù)和其他函數(shù)的偽碼算法;
主函數(shù):
intmain()
ints;
chary=,y,;
cout<<〃|innQQQQnQQnQQQQnQQ菜單QQQQQQnQQ
QQQQQQaaal|z,?endl;
cout<<z,||------------------------【0、創(chuàng)建一個無向圖
-----------------------------||〃<<endl;
cout<m------------------------11、顯示該圖的鄰接矩陣
,,
-------------------------1|?endi;
cout<r||-------------------------【2、顯示該圖的鄰接表
---------------------------1]〃<<endl;
cout?,zH------------------------13、廣度優(yōu)先遍歷
-------------------------------1|〃<<endl;
cout?"||-------------------------【4、深度優(yōu)先遍歷
-------------------------------||〃<<endl;
cout<</z||------------------------[5、最小生成樹MiniSpanTree_PRIM
算法------------1|z,?endl;
cout?/,||------------------------【6、最小生成樹
MiniSpanTree_KRUSCAL算法---------1|"Gendl;
cou^CH------------------------17、連通分量
-----------------------------------||“<<endl;
COUKCIlanaQaaaaanoaaaananaQaaaaQaaa
□□□□□□naali〃?endi;
while(y==,y')
(
cout<<”請選擇菜單:"<<endl;
cin?s;
if(s==0)
(
++o;
if(o==2)
(
n=0;
1=0;
o=0;
1
}
switch(s)
(
case0:cout<X〃創(chuàng)建一個無向圖:〃<Xendl;
MGraph_LG;
creatMGraph_L(G);
ALGraphgra;
creatadj(gra,G);
break;
case1:cout<〈〃鄰接矩陣顯示如下:〃《endl;
1jjzprint(G);
break;
case2:
cout<〈〃鄰接表顯示如下:〃<<endl;
adjprint(gra,G);
break;
case3:
cout?〃廣度優(yōu)先遍歷:〃;
BFSTraverse(gra);
cout<<endl;
break;
case4:
cout<<〃深度優(yōu)先遍歷:〃;
DFStra(gra);
cout<<endl;
break;
case5:
if(n=0){cout<〈〃無權(quán)圖沒有最小生成樹〃;break;}
elseif(l〉O){cout<〈〃若該圖為非強連通圖(含有多個連通分量)時,
最小生成樹不存在〃<<endl;break;}
else
(
inti,g[max][max];
for(i=0;i!=G.vexnum;++i)
for(intj=0;j!=G.vexnum;++j)
g[i+l]Lj+1]=G.arcsEi][j].adj;
cout<<〃普利姆算法:,,<<endl;
MiniSpanTree_PRIM(g,G.vexnum);
break;
)
case6:if(n=0){cout<〈〃無權(quán)圖沒有最小生成樹〃;break;}
elseif(l>0){cout?〃該圖為非強連通圖(含有多個連通分量),最
小生成樹不存在〃<<endl;break;}
else
(
cout<<〃克魯斯卡爾算法:〃〈Vendl;
MiniSpanTREE_KRUSCAL(G,gra);
break;
)
case7:cout<<〃連通分量:〃<<endl;
DFSTraverse_fen(gra);
break;
cout?endl<<〃是否繼續(xù)?y/n:〃;
cin?y;
if(y==,n)
break;
}
return0;
)
鄰接矩陣存儲:
intcreatMGraph_L(MGraph_L&G)〃創(chuàng)建圖用鄰接矩陣表示
(
charvl,v2;
inti,j,w;
cout?!ㄕ堓斎腠旤c和弧的個數(shù)〃<<endl;
cin>>G.vexnum?G.arcnum;
cout<X〃輸入各個頂點〃<Xendl;
for(i=0;i<G.vexnum;++i)
(
cin>>G.vexs[i];
)
for(i=0;i<G.vexnum;++i)
for(j=0;j<G.vexnum;++j)
(
G.arcs[i][j]?adj=int_max;
G.arcs[i][j].info=NULL;
)
for(intk=0;k<G.arcnum;++k)
(
cout<〈〃輸入一條邊依附的頂點和權(quán)〃〈〈endl;
cin>>vl>>v2>>w;〃輸入一條邊依附的兩點及權(quán)值
i=localvex(G,vl);〃確定頂點VI和V2在圖中的位置
j=localvex(G,v2);
G.arcs[i][j].adj=w;
G.arcs[j][i].adj=w;
)
for(i=0;i!=G.vexnum;++i)
for(j=0;j!=G.vexnum;++j)
if(G.arcs[i][j].adj!=1&&G.arcs[i][j].adj<int_max)n+=l;
)
if(n>=l)cout<〈〃這是一個有權(quán)圖〃<<endl;
elsecout<<〃這是一個無權(quán)圖〃<Xendl;
cout*〃圖G鄰接矩陣創(chuàng)建成功!〃<<endl;
returnG.vexnum;
)
鄰接矩陣的輸出:
void1jjzprint(MGraph_LG)〃鄰接矩陣的輸出
(
inti,j;
if(n==0)
(
for(i=0;i!=G.vexnum;++i)
(
for(j=0;j!=G.vexnum;++j)
(
if(G.arcs[i][j].adj==int_max){cout<<〃0〃<<〃〃;}
else{cout<<G.arcs[i][j].adj<<z,〃;}
}
cout<<endl;
)
}
else
(
for(i=0;i!=G.vexnum;++i)
(
for(j=0;j!=G.vexnum;++j)
(
if(G.arcs[i][j].adj==int_max){cout<<〃8〃<<〃〃;}
else{cout<<G.arcs[i][j].adj<<〃〃;}
)
cout?endl;
用鄰接表存儲圖:
intcreatadj(ALGraph&gra,MGraphLG)〃用鄰接表存儲圖
(
inti=0,j=0;
ArcNode*arc;//,*tem,*p;
for(i=0;i!=G.vexnum;++i)
(
gra.vertices[i].data=G.vexs[i];
gra.vertices[i].firstare=NULL;
)
for(i=0;i!=G.vexnum;++i)
for(j=0;j!=G.vexnum;++j)
(
if(G.arcs[i][j].adj!=int_max)
(
arc=(ArcNode*)malloc(sizeof(ArcNode));
arc->adjvex=j;
arc->nextarc=gra.vertices[i]?firstarc;
gra.vertices[i].firstarc=arc;
)
}
gra.vexnum=G.vexnum;
gra.arcnum=G.arcnum;
cout?〃圖G鄰接表創(chuàng)建成功!〃<<endl;
return1;
)
鄰接表輸出:
voidadjprint(ALGraphgra,MGraph_LG)//鄰接表輸出
(
inti;
for(i=0;i!=gra.vexnum;++i)
(
ArcNode*p;
cout?,,r?i?,,/,?G.vexs[i]?,,],z;
p=gra.vertices[i]?firstarc;
while(p!=NULL)
cout?〃->〃<<〃[〃<<p->adjvex<<〃]〃;
p=p->nextarc;
}
cout?//->,,?,,End,z;
cout<<endl;
)
)
初始化隊列:
StatusInitQueue(LinkQueue&Q)〃初始化隊列
(
Q?front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front)return0;〃存儲分配失敗
Q.front->next=NULL;
return1;
)
入隊:
StatusEnQueue(LinkQueue&Q,QElemTypee)〃入隊,插入元素e為Q的新的隊
尾元素
(
QueuePtrp;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)return0;〃存儲分配失敗
p->data=e;p->next=NULL;
Q.rear->next=p;Q.rear=p;
return1;
)
出隊:
StatusDeQueue(LinkQueue&Q,QElemType&e)〃出隊,若隊列不空,則刪除Q
的隊頭元素,用e返回,并返回真,否則假
(
QueuePtrp;
if(Q.front==Q.rear)return0;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
return1;
)
判斷隊為空:
StatusQueueEmpty(LinkQueueQ)〃判斷隊為空
(
if(Q.front==Q.rear)return1;
return0;
)
廣度優(yōu)先遍歷:
voidBFSTraverse(ALGraphgra)
(
inti,e;
LinkQueueq;
for(i=0;i!=gra.vexnum;++i)visited[i]=0;
InitQueue(q);
for(i=0;i!=gra.vexnum;++i)
if(!visited[i])
(
visited[i]=l;
cout<<gra.vertices[i]?data;
EnQueue(q,i);
while(!QueueEmpty(q))
(
DeQueue(q,e);
for(we=firstadjvex(gra,gra.vertices?);we>=0;we=nextadjvex(gra,g
ra.vertices[e],we))
(
if(!visited[we])
(
visited[we]=l;
cout<<gra.vertices[we],data;
EnQueue(q,we);
)
深度優(yōu)先遍歷:
intDFS(ALGraphgra,inti)
(
visited[i]=l;
intwel;
cout<<gra.vertices[i]?data;
for(we=firstadjvex(gra,gra.vertices"]);we>=0;we=nextadjvex(gra,g
ra.vertices[i],we))
(
wel=we;
if(visited[we]-O)
DFS(gra,we);
we=wel;
)
return1;
)
intDFStra(ALGraphgra)
(
inti,j;
for(i=0;i!=gra.vexnum;++i)
(
visited[i]=O;
}
for(j=0;j!=gra.vexnum;++j)
(
if(visited[j]==0)DFS(gra,j);
)
return0;
)
連通分量:
intDFSTraverse_fen(ALGraphgra)
inti,j;
for(i=0;i!=gra.vexnum;++i)
visited[i]=O;
for(j=0;j!=gra.vexnum;++j)
(
if(visited[j]==O)
(
DFS(gra,j);
cout?endl;
1++;
}
)
return0;
)
3.主要函數(shù)的程序流程圖,實現(xiàn)設(shè)計中主程序和其他子模塊的算法,以流程圖
的形式表示。
圖的鄰接矩陣存儲圖的鄰接表存儲圖的廣度優(yōu)先遍歷
<■
開始
Intlowcost[max]
Prevex[max]
IntI,j,k,min
結(jié)束
圖的普利姆算法求最小生成樹
四、調(diào)試分析
1.實際完成的情況說明;
a.先任意創(chuàng)建一個圖;
b.圖的DFS,BFS的遞歸和非遞歸算法的實現(xiàn)
c.最小生成樹(兩個算法)的實現(xiàn),求連通分量的實現(xiàn)
d.要求用鄰接矩陣、鄰接表等多種結(jié)構(gòu)存儲實現(xiàn)
支持的數(shù)據(jù)類型:整型和字符型
2.程序的性能分析,包括時空分析;
本程序的圖的遍歷是以鄰接表做圖的存儲結(jié)構(gòu),其時間復(fù)雜度為0(n+e)。
3.上機過程中出現(xiàn)的問題及其解決方案;
a.程序開始對無權(quán)圖和有權(quán)圖的鄰接矩陣的輸出時,無邊都用的10000(無
窮大int_max)表示的,這種表示和我們習(xí)慣上的0與8的表示有差異。所以在
程序中定義了全局變量n(初值為0),來判斷創(chuàng)建的無向圖是有權(quán)圖還是無權(quán)圖,
n>0為有權(quán)圖,此時輸出的時候用8代替10000;n=0為無權(quán)圖,此時輸出的時
候用0代替10000.
b.程序中有的功能對某些圖是不適用的,比如無權(quán)圖沒有最小生成樹,非強
連通圖沒有最小生成樹等。所以在程序中又新增了全局變量L1>0時表示為非強
連通圖,則在求最小生成樹時報錯。
C.當程序先創(chuàng)建一個有權(quán)圖后,n的值會大于1,第二次創(chuàng)無權(quán)圖時也會被
程序認為有權(quán)圖,所以在程序中在定義全局變量。(初值為0),來判斷創(chuàng)建了幾
次圖,當?shù)诙蝿?chuàng)建圖,即。=2時,所有全局變量在開始全歸零。
4.程序中可以改進的地方說明;
當建立一個圖時先得求其連通分量,從而確定全局變量1的值,從而才能判斷該
圖是否有最小生成樹。
五、測試結(jié)果
創(chuàng)建一個無權(quán)圖:
c:"E:\VC6\lyProjects\^^c4\Debug\test.exe
-------------------------日:顯示該由的穗廨---------------------------
-------------------------【2、顯示該圖的鄰接表-----------------------------
---------------------------------------------13、廣度優(yōu)先遍歷---------------------------------
---------------------------------------------14、深度機先遍歷---------------------------------
---------------------------------------------15、桂箍分量-------------------------------------
---------------------------------------------16、曩個生成忡iniSpanTreeJPRIM算法--------------
-------------------------【7、最小生成樹MiniSpanTree_KRUSCAL算法-----------
在求最小生成樹前請先求連通分量?
請選擇菜單:
創(chuàng)建一個無向圖:
請輸入頂點和弧的個數(shù)
全i入各個頂點
abcdefg
輸入一條邊依附的頂點和權(quán)
ab1
輸入一條邊依附的頂點和權(quán)
ac1
輸入一條邊依附的頂點和權(quán)
bd1
輸入一條邊依附的頂點和權(quán)
be1
輸入一條邊依附的頂點和權(quán)
de1
輸入一條邊依附的頂點和權(quán)
fa1
逡是一個無權(quán)圖
圖G鄰黃矩陣創(chuàng)建成功!
圖G鄰鬟表創(chuàng)建成功!
是否繼續(xù)?i1/n:
03否繼續(xù)?y/n:y
青選擇菜單:
,ji讖續(xù)?y/n:y
郵接矩陣顯示如下:鄰接表顯示如下請選擇菜單:
[0,aJ->[2J->Cl]->End
31100003
[l,b]->[4]->[3J->[0]->End
L00100L度優(yōu)先遍歷:acbedfg
[2,c]->[0]->End
L000000
[3,d]->E4]->riJ->End
3100100是否繼續(xù)?y/n:y
[4,e]->[3]->Ll]->End
3101000請選擇菜單:
L5,f]->[6]->End
3000001
彳000010[6,g]->[5]->End深度優(yōu)先遍歷:acbedfg
是否繼續(xù)?“n:
創(chuàng)建一個費強連通的有權(quán)圖:
歆,E:\VC6\IyProjects\^4\:
習(xí)"E:\VC6\?yPrejects'課設(shè)
請輸入頂點和弧的個數(shù)
55
輸入各個頂點
abede
輸入一條邊依附的頂點和權(quán)
ab2
輸入一條邊依附的頂點和權(quán)
ac3
輸入一條邊依附的頂點和權(quán)
bd1
輸入一條邊依附的頂點和權(quán)
he3
輸入一條邊依附的頂點和權(quán)
de4
這是一個有權(quán)圖
圖G鄰樓矩陣創(chuàng)建成功!
圖G鄰馨表創(chuàng)建成功!
是否繼續(xù)?y/n:y
F選擇菜單:
連通分量:
acbed
是否繼續(xù)?y/n:y
通選擇菜單:
署利拇算法:
<0,1>2
<0,2>3
<1,4>3
是否繼續(xù)?y/n:y
事選擇菜單:
■魯斯卡爾算法:
<0,1>2
<0,2>3
<1,4〉3
是否繼續(xù)?y/n:
六、用戶手冊
c'"E:\¥C6\?yProjects\課設(shè)4\Debug\test.exe"BISE
I
!-------------------------加、創(chuàng)建一無向圖-------------------------------
1---------------------------------------------------0顯示該圖的鄰言矩陣---------------------------:i
1---------------------------------------------------12、顯示該圖的鄰馨表-----------------------------1
!-------------------------【3、匚哪先瀛歷---------------------------------!
?14、深度優(yōu)先遍歷?
;西、他通分里:!
1---------------------------------------------------【6、蜃小生成科MiniSpanTreeJPRIM算法--------------1
最小生,成樹算法-----------
1i-u----a---n----n----u----u----u----n----Q-----Q------u----u----u[7u,nunuunMninaiSQpannTrneeu_KQRUnSCnAuLuunuriuni1
在求最小生成樹前請先求連通分量,
哥選擇菜單:
a.先選0創(chuàng)建一個圖。b.選擇y繼續(xù)操作。c.按照菜單編碼選擇操作。
七、體會與自我評價
在做這個程序的時候你首先必須知道圖的一些概念,圖是一種較線性表和樹
更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。在線性表中,數(shù)據(jù)元素之間僅有線性關(guān)系,每個數(shù)據(jù)元素
只有一個直接前驅(qū)和一個直接后繼;在樹形結(jié)構(gòu)中,數(shù)據(jù)元素之間有著明顯的層
次關(guān)系,并且每一層上的數(shù)據(jù)元素可能和下一層中多個元素(及其孩子結(jié)點)相
關(guān)但只能和上一層中一個元素(即雙親結(jié)點)相關(guān);而在圖形結(jié)構(gòu)中,節(jié)點之間
的關(guān)系可以是任意的,圖中任意兩個數(shù)據(jù)元素之間都可能相關(guān)。
當我們拿到一個圖時,我們對該圖的遍歷就要有一些方法,所以有了深度優(yōu)
先遍歷和廣度優(yōu)先遍歷,我們要明白這兩種遍歷是怎么實現(xiàn)的,然后根據(jù)我們?nèi)?/p>
腦中的方法把它寫成電腦算法。
對一個圖我們還定義了連通分量,所以將圖存到電腦中時,我們對連通分量
得有個算法。
求圖的最小生成樹有兩種算法,普利姆是從結(jié)點出發(fā)尋找權(quán)最小的邊,知道
所有結(jié)點都練通了;而克魯斯卡爾算法則是從邊出發(fā),尋找使圖連通的權(quán)值最小
邊的方法。
算法的實現(xiàn)從人腦到電腦的轉(zhuǎn)變是比較復(fù)雜的一件事,要求做到具體到實現(xiàn)
該方法的每一個步驟,然后再將每一個步驟通過代碼實現(xiàn)。
這要求我們要明確各個數(shù)據(jù)元素和個元素之間的關(guān)系,然后才能明確使用算
法去調(diào)用這些數(shù)據(jù)。
通過本次的課程設(shè)計,我對數(shù)據(jù)結(jié)構(gòu)有了一定的認識,明白了數(shù)據(jù)結(jié)構(gòu)中數(shù)
據(jù),數(shù)據(jù)關(guān)系,及對其操作的方法。但同時也發(fā)現(xiàn)在自己有很多的不足,在使用
語言和如何精煉語言需要進行更多的訓(xùn)練。
源代碼:
#include<iostream>
#include<malloc.h>
usingnamespacestd;
#defineint_max10000〃最大值
staticintn=0;〃全局變量,判斷有權(quán)圖和無權(quán)圖
staticinto=0;〃全局變量,清除BUG
staticini1=0;〃全局變量,清除BUG
#defineinf9999〃最小值的最大值
#definemax20〃最大頂點個數(shù)
typedefintVRType,QElemType,Status;
typedefcharInfoType,VertexType;
//miiiiiiiiiiiwiiiii鄰接矩陣iiiiiuiiiiiiiuiiiiiiiiiiw
//------------------鄰接矩陣定義------------------
typedefstructArcCell
(
VRTypeadj;//VRType是頂點關(guān)系類型。對無權(quán)圖,用1或0表示相鄰否;對帶權(quán)圖,
則為權(quán)值類型
InfoType求info;〃該弧相關(guān)信息的指針
}ArcCell,AdjMatrix[max][max];
typedefstruct
(
VertexTypevexs|max];〃頂點向量
AdjMatrixarcs;〃鄰接矩陣
intvexnum,arcnum;〃圖的當前頂點數(shù)和弧數(shù)
}MGraph_L;
//--------------------------------------------------------------------
intlocalvex(MGraph_LG,charv)〃返回V的位置
(
inti=0;
while(G.vexs[i]!=v)++i;
returni;
)
intcreatMGraph_L(MGraph_L&G)//創(chuàng)建圖用鄰接矩陣表示
(
charvl,v2;
inti,j,w;
coutvv"請輸入頂點和弧的個數(shù)"v<endl;
cin?G.vexnum?G.arcnum;
coutvv"輸入各個頂點"vvendl;
for(i=0;i<Gvexnum;++i)
(
cin?G.vexs[i];
fbr(i=0;i<Gvexnum;4-+i)
for(j=0;j<Gvexnum;++j)
(
Garcs[i][j].adj=int_max;
Garcs[i][j].info=NULL;
)
for(intk=O;k<G.arcnum;++k)
(
cout?"輸入一條邊依附的頂點和權(quán)"vvendl;
cin?v1?v2?w;〃輸入一條邊依附的兩點及權(quán)值
i二k)calvex(G,vl);〃確定頂點VI和V2在圖中的位置
j=localvex(G,v2);
Garcs[i][j].adj=w;
Garcs[j][i].adj=w;
)
for(i=0;i!=Gvexnum;+4-i)
for(j=0;j!=Gvexnum;++j)
(
if(G.arcs[i][j].adj!=l&&G.arcs[i][j].adj<int_max)n+=l;
)
if(n>=l)cout?”這是一個有權(quán)圖”《endl;
elsecout<<"這是一個無權(quán)圖"<<endl;
cout<<”圖G鄰接矩陣創(chuàng)建成功!"《endl;
returnGvexnum;
)
voidljjzprint(MGraph_LG)//鄰接矩陣的輸出
(
inti,j;
if(n==0)
(
fbr(i=O;i!=Gvexnum;++i)
(
for(j=0;j!=Gvexnum;++j)
(
if(G.arcs[i][j].adj==int_max){cout?nO"?nn;}
else{cout?G.arcs[i]fj].adj?,'
}
cout?endl;
)
)
else
{
fbr(i=O;i!=Gvexnum;++i)
for(j=0;j!=Gvexnum;++j)
if(Garcs[i][j].adj-int_max)(cout?"°°"?"";}
else{cout?Garcs[i][j].adj?"";}
)
cout?endl;
)
)
I
//llllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
//-----------------鄰接表的定義----------------
lypedefstructArcNode//弧結(jié)點
(
intadjvex;〃該弧指向的頂點的位置
structArcNode*nextarc;〃指向下一條弧的指針
InfoType*info;〃該弧相關(guān)信息的指針
}ArcNode;
typedefstructVNode〃鄰接鏈表頂點頭接點
(
VertexTypedata;//頂點信息
ArcNode*firstarc;〃指向第一條依附該頂點的弧的指針
(VNode,AdjList;
typedefstruct//圖的定義
(
AdjListvertices!max];
intvexnum,arcnum;〃圖的當前頂點數(shù)和弧數(shù)
}ALGraph;
intcreatadj(ALGraph&gra,MGraph_LG)〃用鄰接表存儲圖
(
inti=0,j=0;
ArcNode*arc;
for(i=0;i!=G.vexnum;++i)
{
gra.vertices[i].data=G.vexs[i];
gra.vertices[i].firstarc=NULL;
)
fdr(i=O;i!=Gvexnum;++i)
for(j=0;j!=G.vexnum;+4j)
(
if(Garcs[i][j].adj!=int_max)
(
arc=(ArcNode*)malloc(sizeof(ArcNode));
arc->adjvex=j;
arc->nextarc=gra.vertices[i].firstarc;
gra.vertices[i].firstarc=arc;
)
gra.vexnum=G.vexnum;
gra.arcnum=G.arcnum;
cout?nSG鄰接表創(chuàng)建成功!n?endl;
return1;
)
voidadjprint(ALGraphgra,MGraph_LG)〃鄰接表輸出
(
inti;
fbr(i=O;i!=gra.vexnum;++i)
(
ArcNode*p;
coutv<”["vvivv",”<vGvexs[i]<v"「;
p=gra.vertices[i].firstarc;
while(p!=NULL)
(
coutvv”->“v<"[“<vp->adjvex<<”『;
p=p->nextarc;
)
cout?',->',?uEnd,';
cout?endl;
)
)
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIN
//----------------隊列定義-----------------
typedefstructQNode
(
QElemTypedata;
structQNode*next;
}QNode,*QueuePtr;
typedefstruct
(
QueuePtrfront;〃隊頭指針
QueuePtrrear;//隊尾指針
(LinkQueue;
//------------------------------------------------------------
StatusInitQueue(LinkQueue&Q)〃初始化隊列
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front)retum0;〃存儲分配失敗
Q.front->next=NULL;
return1;
)
StatusEnQueue(LinkQueue&Q,QElemTypee)〃入隊,插入元素e為Q的新的隊尾元素
(
QueuePtrp;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)return0;//存儲分配失敗
p->data=e;p->next=NULL;
Q.rear->next=p;Q.rear=p;
return1;
}
StatusDeQueue(LinkQueue&Q,QElemType&e)〃出隊,若隊列不空,則刪除Q的隊頭元素,
用e返回,并返回真,否則假
(
QueuePtrp;
if(Q.front==Q.rear)return0;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
return1;
)
StatusQueueEmpty(LinkQueueQ)〃判斷隊為空
(
if(Q.front==Q.rear)return1;
return0;
)
//-------------------圖的遍歷-------------------
intvisited|max];〃訪問標記
intwe;
intfirstadjvex(ALGraphgra,VNodev)〃返回依附頂點V的第一個點
〃即以V為尾的第一個結(jié)點
(
if(v.firstarc!=NULL)returnv.firstarc->adjvex;
)
intnextadjvex(ALGraphgra,VNodev,intw)〃返回依附頂點V的相對于W的下一個頂點
ArcNode*p;
p=v.firstarc;
while(p!=NULL&&p->adjvex!=w)
p=p->nextarc;
)
if(p->adjvex==w&&p->nextarc!=NULL)
(
p=p->nextarc;
returnp->adjvex;
)
if(p->adjvex==w&&p->nextarc==NULL)
return-10;
)
//-------------------廣度優(yōu)先遍歷-------------------
voidBFSTraverse(ALGr叩hgra)
(
inti,e;
LinkQueueq;
fbr(i=O;i!=gra.vexnum;++i)visited[i]=0;
InitQueue(q);
for(i=O;i!=gra.vexnum;++i)
if(!visitedfi])
(
visited[i]=l;
cout?gra.vertices[i].data;
EnQueue(q,i);
while(!QueueEmpty(q))
(
DeQueue(q,e);
fbr(we=firstadjvex(gra,gra.vertices[e]);we>=O;we=nextadjvex(gra,gra.vertices[e],we))
(
if(!visited[we])
(
visited[we]=l;
cout?gra.vertices[we].data;
EnQueue(q,we);
)
)
)
)
)
//----------------------深度優(yōu)先遍歷----------------------
intDFS(ALGraphgra,inti)
visited[i]=l;
intwel;
cout?gra.vertices[i].data;
for(we=firstadjvex(gra,gra.vertices[i]);we>=O;we=nextadjvex(gra,gra.vertices[i],we))
(
wel=we;
if(visited[we]==O)
DFS(gra,we);
we=wel;
)
return1;
)
intDFStra(ALGraphgra)
(
inti,j;
fbr(i=O;i!=gra.vexnum;++i)
(
visited[i]=O;
)
fbr(j=O;j!=gra.vexnum;++j)
(
if(visited|j]==O)DFS(gra,j);
)
return0;
)
//-------------------求連通分量...............——
intDFSTraverse_fen(ALGraphgra)
(
inti,j;
for(i=0;i!=gra.vexnum;++i)
visited[i]=0;
for(j=0;j!=gra.vexnum;++j)
(
if(visited[jl==0)
{
DFS(gra,j);
coul?endl;
1++;
)
)
return0;
)
//--------------------最小生成樹的普利姆算法--------------------
typedefstruct
intadjvex;
intlowcost;
Jclosedge;
intMiniSpanTree_PRIM(intg[][max],intn)
(
intlowcost[max],prevex[max];//lowcost口存儲當前集合分別到剩余結(jié)點的最小權(quán)值
//prevex口存儲最短路徑的前一個結(jié)點
inti,j,k,min;
for(i=2;i<=n;i++)//n個頂點,n?l條邊
(
k)wcost[i]=g[l][i];//初始化
prevex[i]=l;//頂點未加入到最小生成樹中
)
lowcost[l]=0;〃標志頂點1加入U集合
for(i=2;iv=n;i++)〃形成n-1條邊的生成樹
(
min=inf;
k=0;
for(j=2;j<=n;j++)//尋找滿足邊的一個頂點在U,另一個頂點在V的最小邊
if((lowcost[j]<min)&&(lowcost[j]!=0))
(
min=lowcost|j];
k=j;
)
cout?,'(',?prevex[k]-1?",M?k-1?,,),'?min;
lowcosl[k]=0;//頂點k加入U
for(j=2;jv=n;j++)〃修改由頂點k到其他頂點邊的權(quán)值
if(g[k][j]<lowcost[j])
(
lowcost[j]=g[k][j];
prevex|j]=k;
)
cout?endl;
}
return0;
}
//-----------------最小生成樹的克魯斯卡爾算法-------------------
intacrvisitedfmax];〃克魯斯卡爾弧標記數(shù)組
intfind(intacrvisited[],intf)
(
while(acrvisited[f]>O)f=acrvisited[f];
returnf;
typedefstructacr
intpre;〃弧的一結(jié)點
intbak;〃弧另一結(jié)點
intweight;〃弧的權(quán)
}edg;
voidMiniSpanTREE_KRUSCAL(MGraph_LQALGraphgra)
(
edgedgs[max];
inti,j,k=O;
for(i=O;i!=Gvexnum;++i)
for(j=i;j!=G.vexnum;++j)
(
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 接樁專項施工方案
- 機柜間施工方案
- 二零二五年度美甲店知識產(chǎn)權(quán)保護與專利申請合同4篇
- 高效害蟲防治與建筑保護合同2025年度版4篇
- 部編人教版七年級上冊語文《少年正是讀書時》教學(xué)設(shè)計
- 2025年度新能源車輛掛名權(quán)轉(zhuǎn)讓及免責(zé)保障協(xié)議范本4篇
- 2025年版酒店餐飲行業(yè)食品安全與售后服務(wù)標準協(xié)議3篇
- 二零二五年船舶安全監(jiān)督與船員資質(zhì)審核協(xié)議3篇
- 2025年度商業(yè)空間瓷磚定制及安裝服務(wù)合同4篇
- 二零二五版蒙娜麗莎瓷磚環(huán)保認證與市場準入?yún)f(xié)議4篇
- 招標師《招標采購項目管理》近年考試真題題庫(含答案解析)
- 微生物組與唾液腺免疫反應(yīng)-洞察分析
- 2024公共數(shù)據(jù)授權(quán)運營實施方案
- 《向心力》 教學(xué)課件
- 結(jié)構(gòu)力學(xué)數(shù)值方法:邊界元法(BEM):邊界元法的基本原理與步驟
- 北師大版物理九年級全一冊課件
- 2024年第三師圖木舒克市市場監(jiān)督管理局招錄2人《行政職業(yè)能力測驗》高頻考點、難點(含詳細答案)
- RFJ 006-2021 RFP型人防過濾吸收器制造與驗收規(guī)范(暫行)
- 盆腔炎教學(xué)查房課件
- 110kv各類型變壓器的計算單
- 新概念英語課件NCE3-lesson15(共34張)
評論
0/150
提交評論