c語言實現圖的鄰接表存儲方式

有向圖的鄰接表實現

初學圖的鄰接表存儲方式,費了很多的時間去理解它。走了很多彎路,終於用代碼上實現了這個存儲結構,在這裏把的感悟和過程做個總結,希望能幫到和我一樣的初學者。

對於以下這個圖
在這裏插入圖片描述
它的鄰接表存儲結構我相信大部分的朋友肯定是能夠理解的,但是大部分的資料講解都是在畫一個鄰接表的結構表示圖之後直接上代碼,然後對代碼進行解釋。

但對與我這樣的初學者來說,這個由理論到代碼的中間轉換過程其實是最難理解的。我看了很多的博文,圖的創建差不多都一樣用一個函數進行邊節點的不斷插入。爲了更容易理解這個創建的過程我用一個比較麻煩的方法去實現上圖中圖的存儲

完整代碼

#include<stdio.h>
#include<stdlib.h>
#define MAX 10
int visit[MAX]={0};
//以下結構體的創建和大部分資料的相同
typedef struct arcNode{//邊節點
    int adjvex;//邊指向的頂點編號,從0到4;這個和頂點信息
              //不一樣哦        
   
    struct arcNode *next;//用於指向下一個arcnode節點
}arcNode;
typedef struct vNode{/*表頭節點,也就是鄰接表中每個單鏈表                       的表頭,存儲的是每一個頂點*/

    char data;/*這個是頂點信息,比如在其他資料中,這個用來
              表示v0,v1,v2,v3之類的,只是這裏舉的例子
             剛好是頂點爲0,1,2,3,4*/
    arcNode *firstArc;//就是表頭指向的第一個邊節點
}vNode;
typedef struct graph{
    vNode adjlist[MAX];/*用順序表來存儲每一個表頭,從而                         實現圖的鄰接表存儲結構*/
    int e;//圖的頂點數目
    int n;//圖的頂點數目
}graph;

void createGraph(graph *G){//創建一個圖
    int i;
    arcNode *arc[G->e] ;//定義n個邊節點
    for(i=0;i<G->n;i++){//圖的表頭節點初始化
        G->adjlist[i].firstArc = NULL;//置空
        G->adjlist[i].data = '0'+i;//圖的頂點信息,不是編號哦
    }
    for(i=0;i<G->e;i++){//初始化n個邊節點
        arc[i] = (arcNode*)malloc(sizeof(arcNode));
    }
    //接下來開始手動一個搭建一個圖
    //第一條鏈表,以adjlist[0]爲表頭
    G->adjlist[0].firstArc = arc[0];//arc[0]爲表頭節點0的第一條邊,也就是0->1
    arc[0]->adjvex = 1;
    arc[0]->next =arc[1];//arc[0]邊節點指向下一條邊節點,也就是0->1->3
    arc[1]->adjvex = 3;
    arc[1]->next = arc[2];//同理0->1->3->4
    arc[2]->adjvex = 4;
    arc[2]->next = NULL;
    //第二條鏈表,以adjlist[1]爲表頭
    G->adjlist[1].firstArc = arc[3];//arc[3]成爲表頭節點1的第一條邊,也就是1->
    arc[3]->adjvex = 4;
    arc[3]->next = arc[4];
    arc[4]->adjvex = 2;
    arc[4]->next = NULL;
    //第三條鏈表,以adjlist[2]爲表頭
    G->adjlist[2].firstArc = arc[5];
    arc[5]->adjvex = 0;
    arc[5]->next = NULL;
    
    G->adjlist[3].firstArc = arc[6];
    arc[6]->adjvex = 2;
    arc[6]->next = NULL;
    
    G->adjlist[4].firstArc = NULL;
}
void DFS(graph *G,int v){//深度遍歷
    arcNode *p ;
    if(visit[v]==0){
    visit[v] = 1;//定義了一個int型數組visit來標記每個頂點是否被遍歷過
    printf("%c   ",G->adjlist[v].data);//輸出頂點
    p = G->adjlist[v].firstArc;//將每個頂點的下一個邊節點賦給p節點
    while(p!=NULL){//循環遍歷p所指向的下一個邊節點
        if(visit[p->adjvex]==0){
            DFS(G,p->adjvex);
        }
        p=p->next;
    }
    }
}
int main(){
    graph *G = (graph*)malloc(sizeof(graph));
    G->e=7;//這個圖的邊有7條邊
    G->n=5;//5個頂點
    createGraph(G);
    printf("\n");
    DFS(G, 0);
    return 0;
}

以上是我的愚解,如有不當的地方還望多指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章