tft每日頭條

 > 生活

 > 用c語言建立鄰接矩陣

用c語言建立鄰接矩陣

生活 更新时间:2024-07-21 21:29:16

圖(Graph)是由頂點(Vertex)的有窮非空集合和頂點之間邊(Edge)的集合組成,通常表示為:G(V,E),其中,G表示一個圖,V是圖G中頂點的集合,E是圖G中邊的集合。圖中的數據元素,我們稱之為頂點(Vertex),頂點集合有窮非空。在圖中,任意兩個頂點之間都可能有關系,頂點之間的邏輯關系用邊來表示,邊集可以是空的。

圖的鄰接矩陣(Adjacency Matrix)存儲方式是用兩個數組來表示圖。

用一個順序表來存儲頂點信息

用鄰接矩陣(二維數組)表示頂點間的相鄰關系

圖按照有無方向分為無向圖和有向圖。無向圖由頂點和邊組成,有向圖由頂點和弧構成。弧有弧尾和弧頭之分,帶箭頭一端為弧頭。

圖中頂點之間有鄰接點、依附的概念。無向圖頂點的邊數叫做度。有向圖頂點分為入度和出度。

圖上的邊或弧帶有權則稱為網。

在一個圖中,每條邊或弧可以擁有一個與之相關的數值,我們将它稱為權。這些權可以具有一定的含義,比如,表示一個頂點到達另一個頂點的距離、所花費的時間、線路的造價等等。這種帶權的圖通常被稱作網。

圖中頂點間存在路徑,兩頂點存在路徑則說明是連通的,如果路徑最終回到起始點則稱為環,當中不重複的叫簡單路徑。若任意兩頂點都是連通的,則圖就是連通圖,有向則稱為強連通圖。圖中有子圖,若子圖極大連通則就是連通分量,有向的則稱為強連通分量。

圖的鄰接矩陣的存儲結構定義如下:

#define MVNum 50 //最大頂點數

typedef struct{

VertexType vexs[MVNum];

Adjmatrix arcs[MVNum[MVNum];

}MGraph

下圖是一個4個頂點的無向圖:

無權無向圖的鄰接矩陣可定義為:

用c語言建立鄰接矩陣(圖的鄰接矩陣和最短路徑)1

用c語言建立鄰接矩陣(圖的鄰接矩陣和最短路徑)2

下圖是一個4個頂點的有向圖:

用c語言建立鄰接矩陣(圖的鄰接矩陣和最短路徑)3

在圖的術語中,我們提到了網的概念,也就是每條邊上都帶有權的圖叫做網。那些這些權值就需要保存下來。

設圖G是網圖,有n個頂點,則鄰接矩陣是一個n*n的方陣,定義為:

用c語言建立鄰接矩陣(圖的鄰接矩陣和最短路徑)4

下圖是一個有向網圖。

用c語言建立鄰接矩陣(圖的鄰接矩陣和最短路徑)5

最短路徑代碼:

#include <stdio.h>

#include <stdlib.h>

#define MVNum 100 //最大頂點數

#define Maxint 32767

typedef char VertexType;

typedef int Adjmatrix;

typedef enum {FALSE,TRUE} boolean; //定義布爾型

typedef struct {

VertexType vexs[MVNum]; //頂點數組,類型假定為char型

Adjmatrix arcs[MVNum][MVNum]; //鄰接矩陣,假定為int型

}MGraph;

//全局數組

int D1[MVNum],P1[MVNum];

int D[MVNum][MVNum],P[MVNum][MVNum];

//聲明函數原型

void CreateMGraph(MGraph *,int ,int );

void Dijkstra(MGraph,int,int );

void Floyd(MGraph ,int);

void displayNode(MGraph *,int);

//主程序

void main( )

{ MGraph G;

int n,e,v,w,k;

int xz=1;

printf("輸入圖中頂點個數和邊數n,e:");

scanf("%d %d",&n,&e);

CreateMGraph(&G,n,e);//建立圖的存儲結構

displayNode(&G,n);

while (xz!=0) {

printf("******求城市之間的最短路徑******\n");

printf("================================\n");

printf("1.求一個城市到所有城市的最短路徑\n");

printf("2.求任意的兩個城市之間的最短路徑\n");

printf("================================\n");

printf(" 請選擇:1 或 2,選擇 0 退出 :");

scanf("%d",&xz);

if(xz==2) {

Floyd(G,n); //調用費洛伊德算法

printf(" 輸入源點(或稱起點)和終點:v,w :");

scanf("%d %d",&v,&w);

k=P[v][w]; //k為起點v的後繼頂點

if(k==0)

printf("頂點 %d 到 %d 無路徑!\n",v,w);

else

{

printf("從頂點%d到%d的最短路徑是:%d",v,w,v);

while(k!=w) {

printf("→%d",k); //輸出後繼頂點

k=P[k][w]; //繼續找下一個後繼頂點

}

printf("→%d\n",w); //輸出終點w

printf(" 路徑長度:%d\n",D[v][w]);

}

}

else

if(xz==1) {

printf("求單源路徑,輸入源點 v :");

scanf("%d",&v);

Dijkstra(G,v,n); //調用迪傑斯特拉算法

}

// xz=0;

}

printf("結束求最短路徑,再見!\n");

system("pause");

}

void CreateMGraph(MGraph* G,int n,int e)

{//采用鄰接矩陣表示法構造有向網G, n、e表示圖的當前頂點數和邊數

int i,j,k,w;

for(i=1;i<=n;i )//輸入頂點信息

G->vexs[i]=(char)i;

for(i=1;i<=n;i )

for(j=1;j<=n;j )

G->arcs[i][j]=Maxint;//初始化鄰接矩陣

printf("輸入%d條邊的i、j及w:\n",e);

for(k=1;k<=e;k ){ //讀入e條邊,建立鄰接矩陣

scanf("%d %d %d",&i,&j,&w);

G->arcs[i][j]=w;

}

printf("有向圖的存儲結構建立完畢!\n");

}

void displayNode(MGraph *G,int m)

{

int i,j;

printf("圖的鄰接矩陣為:\n");

for(i=1;i<=m;i )

{

for(j=1;j<=m;j )

printf("d",G->arcs[i][j]);

printf("\n");

}

}

//迪傑斯特拉算法

void Dijkstra(MGraph G,int v1,int n)

{ //用Dijkstra算法求有向圖G的v1頂點到其他頂點v的最短路徑P[v]及其權D[v]

//設G是有向網的鄰接矩陣,若邊<i,j>不存在,則G[i][j]=Maxint

//S[v]為真當且僅當v∈S,即已求得從v1到v的最短路徑

int D2[MVNum],P2[MVNum];

int v,i,w,min;

boolean S[MVNum];

for(v=1;v<=n;v ){//初始化S和D

S[v]=FALSE; //置空最短路徑終點集

D2[v]=G.arcs[v1][v]; //置初始的最短路徑值

if(D2[v]<Maxint)

P2[v]=v1; //v1是v的前趨(雙親)

else

P2[v]=0; //v無前趨

}//end_for

D2[v1]=0;S[v1]=TRUE; //S集初始時隻有源點,源點到源點的距離為0

//開始循環,每次求得v1到某個v頂點的最短路徑,并加v到S集中

for(i=2;i<n;i )

{//其餘n-1個頂點

min=Maxint;

for(w=1;w<=n;w )

if(!S[w] && D2[w]<min)

{

v=w;

min=D2[w];

}//w頂點離v1頂點更近

S[v]=TRUE;

for(w=1;w<=n;w )//更新當前最短路徑及距離

if(!S[w]&&(D2[v] G.arcs[v][w]<D2[w]))

{ //修改D2[w]和P2[w],w∈V-S

D2[w]=D2[v] G.arcs[v][w];

P2[w]=v;

}//End_if

}//End_for

printf("路徑長度 路徑\n");

for(i=1;i<=n;i )

{

printf("]",D2[i]);

printf("]",i);v=P2[i];

while(v!=0) {

printf("<-%d",v);

v=P2[v];

}

printf("\n");

}

}

//費洛伊德算法

void Floyd(MGraph G,int n)

{

int i,j,k;

for(i=1;i<=n;i ) //設置路徑長度D和路徑path初值

for(j=1;j<=n;j )

{

if(G.arcs[i][j]!=Maxint)

P[i][j]=j; //j是i的後繼

else

P[i][j]=0;

D[i][j]=G.arcs[i][j];

}

for(k=1;k<=n;k )

{//做k次疊代,每次均試圖将頂點k擴充到當前求得的從i到j的最短路徑Pij上

for(i=1;i<=n;i )

for(j=1;j<=n;j )

{

if(D[i][k] D[k][j]<D[i][j])

{

D[i][j]= D[i][k] D[k][j]; //修改長度

P[i][j]=P[i][k];

}

}

}

}

有如下有向圖,為了操作方便,對于圖的頂點都用序号來表示,頂點的字母用對應的序号來操作:a(1),b(2),c(3),d(4),e(5),f(6),g(7)。

用c語言建立鄰接矩陣(圖的鄰接矩陣和最短路徑)6

運行效果如下:

輸入圖中頂點個數和邊數n,e(空格分隔):7 10

輸入10條邊的i、j(矩陣行列或坐标值)及w(權值,如距離、花費時間等):

1 7 9

2 1 20

2 3 10

2 4 20

3 5 5

5 4 12

5 7 15

6 5 18

6 7 10

7 3 18

有向圖的存儲結構建立完畢!

圖的鄰接矩陣為:

32767 32767 32767 32767 32767 32767 9

20 32767 10 20 32767 32767 32767

32767 32767 32767 32767 5 32767 32767

32767 32767 32767 32767 32767 32767 32767

32767 32767 32767 12 32767 32767 15

32767 32767 32767 32767 18 32767 10

32767 32767 18 32767 32767 32767 32767

******求城市之間的最短路徑******

================================

1.求一個城市到所有城市的最短路徑

2.求任意的兩個城市之間的最短路徑

================================

請選擇:1 或 2,選擇 0 退出 :1

求單源路徑,輸入源點 v :1

路徑長度 路徑

0 1

32767 2

27 3<-7<-1

44 4<-5<-3<-7<-1

32 5<-3<-7<-1

32767 6

9 7<-1

******求城市之間的最短路徑******

================================

1.求一個城市到所有城市的最短路徑

2.求任意的兩個城市之間的最短路徑

================================

請選擇:1 或 2,選擇 0 退出 :2

輸入源點(或稱起點)和終點:v,w :1 4

從頂點1到4的最短路徑是:1→7→3→5→4

路徑長度:44

******求城市之間的最短路徑******

================================

1.求一個城市到所有城市的最短路徑

2.求任意的兩個城市之間的最短路徑

================================

請選擇:1 或 2,選擇 0 退出 :2

輸入源點(或稱起點)和終點:v,w :4 7

頂點 4 到 7 無路徑!

******求城市之間的最短路徑******

================================

1.求一個城市到所有城市的最短路徑

2.求任意的兩個城市之間的最短路徑

================================

請選擇:1 或 2,選擇 0 退出 :0

結束求最短路徑,再見!

有如下有向網圖:

用c語言建立鄰接矩陣(圖的鄰接矩陣和最短路徑)7

運行結果:

輸入圖中頂點個數和邊數n,e(空格分隔):7 20

輸入20條邊的i、j(矩陣行列或坐标值)及w(權值,如距離、花費時間等):

1 2 2553

2 1 2553

1 3 695

3 1 695

1 4 704

4 1 704

2 3 511

3 2 511

2 5 812

5 2 812

3 4 349

4 3 349

3 6 1579

6 3 1579

4 7 651

7 4 651

5 6 2368

6 5 2368

6 7 1385

7 6 1385

有向圖的存儲結構建立完畢!

******求城市之間的最短路徑******

================================

1.求一個城市到所有城市的最短路徑

2.求任意的兩個城市之間的最短路徑

================================

請選擇:1 或 2,選擇 0 退出 :1

求單源路徑,輸入源點 v :1

路徑長度 路徑

0 1

1206 2<-3<-1

695 3<-1

704 4<-1

2018 5<-2<-3<-1

2274 6<-3<-1

1355 7<-4<-1

******求城市之間的最短路徑******

================================

1.求一個城市到所有城市的最短路徑

2.求任意的兩個城市之間的最短路徑

================================

請選擇:1 或 2,選擇 0 退出 :2

輸入源點(或稱起點)和終點:v,w :5 7

從頂點5到7的最短路徑是:5→2→3→4→7

路徑長度:2323

******求城市之間的最短路徑******

================================

1.求一個城市到所有城市的最短路徑

2.求任意的兩個城市之間的最短路徑

================================

請選擇:1 或 2,選擇 0 退出 :2

輸入源點(或稱起點)和終點:v,w :7 2

從頂點7到2的最短路徑是:7→4→3→2

路徑長度:1511

******求城市之間的最短路徑******

================================

1.求一個城市到所有城市的最短路徑

2.求任意的兩個城市之間的最短路徑

================================

請選擇:1 或 2,選擇 0 退出 :0

結束求最短路徑,再見!

請按任意鍵繼續. . .

-End-

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved