圖的鄰接矩陣和DFS遍歷
阿新 • • 發佈:2019-02-18
圖的儲存結構相對於線性表和樹來說,是複雜了許多,而不是用一個線性表或者連結串列就能定義的。對於圖來說,它的儲存方式有鄰接矩陣,鄰接表,十字連結串列,鄰接多重表和邊集陣列。在這裡,要介紹的是如果使用鄰接矩陣和鄰接表來儲存圖結構。
一、鄰接矩陣
圖的鄰接矩陣儲存是用兩個陣列來完成的。一個一維陣列儲存定點資訊(稱為頂點陣列),一個二維陣列儲存邊資訊(稱為邊陣列)。
下面介紹不同型別的鄰接矩陣的定義。
1. 無向圖的鄰接矩陣
(1) 無權圖的鄰接矩陣
無權圖G=(V,E)的定義如下:
(2)有權圖的鄰接矩陣
無權圖G=(V,E)的定義如下:
2. 有向圖的鄰接矩陣
(1) 無權圖的鄰接矩陣
無權圖G=(V,E)的定義如下:
(2)有權圖的鄰接矩陣
無權圖G=(V,E)的定義如下:
可以看到,對於無權圖來說,0表示此邊( i , j )或< i , j >不存在,1則反之;對於有權圖來說,具體的數值表示此邊( i , j )或< i , j >的權值,而無窮符號則表示此邊不存在。
程式碼實現
假如我們要對此圖建立鄰接矩陣
則建立的頂點陣列和鄰接矩陣如下:
#include <stdio.h>
#include <stdlib.h>
//const int MAXVEX = 100;
#define MAXVEX 100
#define INFINITT 65535 //表示無窮
int visited[MAXVEX];
typedef struct{
char vexs[MAXVEX];//頂點表
int arc[MAXVEX][MAXVEX];//邊表
int numV, numE;//頂點數和邊數
}MGraph;
void createGraph(MGraph *G){
int i,j,k,w;
printf("請輸入頂點數和邊數:");
scanf("%d%d", &G->numV, &G->numE);
//建立結點
for (i = 0; i < G->numV; i++){
scanf("%d", &G->vexs[i]);
}
//初始化邊為無窮
for(i = 0; i < G->numV; i++){
for(j = 0; j < G->numV; j++){
G->arc[i][j] = INFINITT;
}
}
//建立邊
printf("輸入邊的左右兩個座標:\n");
for(k = 0; k < G->numE; k++){
scanf("%d%d%d", &i,&j,&w);
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j];
}
}
int main(){
MGraph G;
createGraph(&G);
}
二、圖的DFS遍歷
圖的DFS遍歷,類似樹的DFS遍歷。從圖中的某個頂點v開始,訪問此節點,然後從v的未訪問的鄰接點開始再進行DFS遍歷,直到所有和v想通的頂點都被訪問到。
程式碼實現
void DFS(MGraph G, int i){
int j;
printf("%d ", G.vexs[i]);
visited[i] = 1;
for(j = 0; j < G.numV; j++){
if(G.arc[i][j] != 0 && G.arc[i][j] != INFINITT && !visited[j]){
DFS(G, j);
}
}
}
void DFSTraverse(MGraph G){
int i;
for(i = 0; i < G.numV; i++){
visited[i] = 0;
}
for(i = 0; i < G.numV; i++){
if(!visited[i]){
DFS(G, i);
}
}
}
完整程式碼
include <stdlib.h>
//const int MAXVEX = 100;
#define MAXVEX 100
#define INFINITT 65535 //表示無窮
int visited[MAXVEX];
typedef struct{
char vexs[MAXVEX];//頂點表
int arc[MAXVEX][MAXVEX];//邊表
int numV, numE;//頂點數和邊數
}MGraph;
void createGraph(MGraph *G){
int i,j,k,w;
printf("請輸入頂點數和邊數:");
scanf("%d%d", &G->numV, &G->numE);
//建立結點
for(i = 0; i < G->numV; i++){
scanf("%d", &G->vexs[i]);
}
//初始化邊為無窮
for(i = 0; i < G->numV; i++){
for(j = 0; j < G->numV; j++){
G->arc[i][j] = INFINITT;
}
}
//建立邊
printf("輸入邊的左右兩個座標:\n");
for(k = 0; k < G->numE; k++){
scanf("%d%d%d", &i,&j,&w);
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j];
}
}
void DFS(MGraph G, int i){
int j;
printf("%d ", G.vexs[i]);
visited[i] = 1;
for(j = 0; j < G.numV; j++){
if(G.arc[i][j] != 0 && G.arc[i][j] != INFINITT && !visited[j]){
DFS(G, j);
}
}
}
void DFSTraverse(MGraph G){
int i;
for(i = 0; i < G.numV; i++){
visited[i] = 0;
}
for(i = 0; i < G.numV; i++){
if(!visited[i]){
DFS(G, i);
}
}
}
int main(){
MGraph G;
createGraph(&G);
DFSTraverse(G);
}
結果如下: