1. 程式人生 > >圖的鄰接矩陣和DFS遍歷

圖的鄰接矩陣和DFS遍歷

圖的儲存結構相對於線性表和樹來說,是複雜了許多,而不是用一個線性表或者連結串列就能定義的。對於圖來說,它的儲存方式有鄰接矩陣,鄰接表,十字連結串列,鄰接多重表和邊集陣列。在這裡,要介紹的是如果使用鄰接矩陣和鄰接表來儲存圖結構。

一、鄰接矩陣

圖的鄰接矩陣儲存是用兩個陣列來完成的。一個一維陣列儲存定點資訊(稱為頂點陣列),一個二維陣列儲存邊資訊(稱為邊陣列)。
下面介紹不同型別的鄰接矩陣的定義。

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);
}

結果如下:

這裡寫圖片描述