標籤:
先簡要列出實現過程中所需要的資料結構。
如
對於這個圖而言,它的鄰接表可以這樣表示,當然表現形式可以多樣,這隻是我隨便畫的一種表示方法。
頂點表 邊表
我們把第一個表即上面標著fixedvex的這個表稱作頂點表,後邊的稱為邊表。
所示,邊表的結構應該這樣寫:
//定義一個邊表節點的結構 typedef struct node{int adjvex;//int Mark; //用於標記是否被訪問過 node *next;}VerAndedge;
包含一個adjvex,儲存某個結點;
一個next指向下個邊表結構,構成各個頂點間的聯絡。
既然有了邊表的結構,那麼頂點表的結構應該如下:
//頂點表 typedef struct Fixed{ int Mark; int fixedvex; node* firsthead;}Fixednode;
包含一個fixedvex儲存頂點;
由圖中可知,頂點表指向邊表,所以理所當然包含一個指向邊表的指標:一個 firsthead ;
有了以上這2個結構,我們便可以著手開始實現它了。
首先明確要有幾個結點,也就是要有幾個 fixedvex ,由於每個fixedvex都有其特定的關係,所以我們應該產生結構數組來儲存這些內容,所以我們再建立如下的結構儲存,為什麼建立這個結構?下面將清晰。
//儲存各個頂點資訊。 typedef struct ALgarph{ int a,b; Fixednode adjlist[100];}ALgarph;
既然要建立一個鄰接表,那就寫一個函數吧
void creat(ALgarph *);
首先必須對這個函數傳入內容,那我們便建立一個結構,並傳入
ALgarph *S = (ALgarph*)malloc(sizeof(ALgarph));
creat(S);
這個creat到底怎麼寫呢,下面直接給出代碼,讀者通過注釋自己理解。
void creat(ALgarph *S){ int i,x,y; printf("請輸入頂點的個數和邊的數量:"); scanf("%d%d",&S->a,&S->b); //擷取到頂點和邊的資訊 for(i=0;i<S->a;i++) { printf("輸入頂點,建立頂點表:"); //建立頂點表。 scanf("%d",&S->adjlist[i].fixedvex); S->adjlist[i].firsthead= NULL; //初始化firsthead S->adjlist[i].Mark = 0;//初始化標記 } printf("建立邊表\n");//建立邊表,在建立的同時將他們的關係對應 for(i=0;i<S->b;i++) { printf("讀入(vi-vj):"); scanf("%d%d",&x,&y); VerAndedge * G = (VerAndedge *)malloc(sizeof(VerAndedge)); //產生一個邊表結構 // G->Mark = 0; //標記為零表示未訪問 G->adjvex= y; G->next= S->adjlist[x].firsthead; //插入到頭部 S->adjlist[x].firsthead= G; //因為是無向圖,所以調換個節點的關係,再次產生。 G= (VerAndedge *)malloc(sizeof(VerAndedge)); // G->Mark = 0; G->adjvex= x; G->next= S->adjlist[y].firsthead; //插入到頭部 S->adjlist[y].firsthead= G; }}
建立完畢後就是輸出這個鄰接表了。
VerAndedge *current; for(i=0;i<S->a;i++) { printf("%d->",S->adjlist[i].fixedvex); current = S->adjlist[i].firsthead; while(current!=NULL) { printf("%d->",current->adjvex); current= current->next; } printf("\n"); }
好了,那麼完整的程式如下:
/*2014/12/1*//*鄰接表表示的圖的深度優先遍曆*//*這個代碼是在昨天的基礎上改寫了,添加了DFS遍曆的2個函數,注釋著實覺得沒有添加的必要.反正是採用了遞迴的方法 */#include <stdio.h>#include <stdlib.h>//定義一個邊表節點的結構 typedef struct node{ int adjvex; //int Mark; //用於標記是否被訪問過 node *next;}VerAndedge; //頂點表 typedef struct Fixed{ int Mark; int fixedvex; node* firsthead;}Fixednode;//儲存各個頂點資訊。 typedef struct ALgarph{ int a,b; Fixednode adjlist[100];}ALgarph;void creat(ALgarph *);void Adj_dfs(ALgarph *);void Adj_visit(ALgarph * ,int); int main(void){ int i; ALgarph * S = (ALgarph *)malloc(sizeof(ALgarph)); creat(S); VerAndedge *current; for(i=0;i<S->a;i++) { printf("%d->",S->adjlist[i].fixedvex); current = S->adjlist[i].firsthead; while(current!=NULL) { printf("%d->",current->adjvex); current= current->next; } printf("\n"); } Adj_dfs(S); return 0;} void creat(ALgarph *S){ int i,x,y; printf("請輸入頂點的個數和邊的數量:"); scanf("%d%d",&S->a,&S->b); //擷取到頂點和邊的資訊 for(i=0;i<S->a;i++) { printf("輸入頂點,建立頂點表:"); //建立頂點表。 scanf("%d",&S->adjlist[i].fixedvex); S->adjlist[i].firsthead= NULL; //初始化firsthead S->adjlist[i].Mark = 0;//初始化標記 } printf("建立邊表\n");//建立邊表,在建立的同時將他們的關係對應 for(i=0;i<S->b;i++) { printf("讀入(vi-vj):"); scanf("%d%d",&x,&y); VerAndedge * G = (VerAndedge *)malloc(sizeof(VerAndedge)); //產生一個邊表結構 // G->Mark = 0; //標記為零表示未訪問 G->adjvex= y; G->next= S->adjlist[x].firsthead; //插入到頭部 S->adjlist[x].firsthead= G; //因為是無向圖,所以調換個節點的關係,再次產生。 G= (VerAndedge *)malloc(sizeof(VerAndedge)); // G->Mark = 0; G->adjvex= x; G->next= S->adjlist[y].firsthead; //插入到頭部 S->adjlist[y].firsthead= G; }}void Adj_dfs(ALgarph *S){ int vi; printf("請輸入源點:\n"); scanf("%d",&vi); printf("遍曆結果如下:"); Adj_visit(S,vi);}void Adj_visit(ALgarph * S,int vi){ if(S->adjlist[vi].Mark == 0) { printf("%-2d",S->adjlist[vi].fixedvex); S->adjlist[vi].Mark = 1; } VerAndedge * current = S->adjlist[vi].firsthead; for(;current!=NULL;current=current->next) { if(S->adjlist[current->adjvex].Mark==0) Adj_visit(S,current->adjvex); } }
運行結果如下
圖的鄰接表格儲存體c實現(DFS遍曆)