我們先來看一個圖

我們想將這個圖的信息存儲到鄰接表中,我們需要一個數組保存節點信息,還要有一個節點用來保存與該節點相鄰的節點信息.
1 typedef struct arc_node 2 { 3 int pos; 4 int distance; 5 struct arc_node * next; 6 } Arc_node;//保存Node節點的相鄰節點信息 7 8 typedef struct node 9 { 10 node_type info; 11 Arc_node * next; 12 } Node;//保存節點信息 13 14 typedef struct graph 15 { 16 Node vertexs[MAX_NUM]; 17 int vertex, arc; 18 } Graph;//鄰接表
如果將上面的圖用鄰接表存儲,我們將回看到這樣一幅圖

每個字符后面的數字代表與它相鄰的節點在數組中的位置(在Arc_node里存有權值,這里沒有顯示)
構造鄰接表:
1)先輸入節點個數及節點信息.
2)在輸入某節點的相鄰節點及權值.(這時,每輸入一個相鄰節點,就構建一個Arc_node節點,將Arc_node接到該節點的最后)
1 void g_create(Graph * graph) 2 { 3 int num; 4 int i, j, k; 5 char c; 6 Arc_node * tmp; 7 8 printf("輸入節點個數:"); 9 scanf("%d", &graph->vertex); 10 getchar(); 11 printf("輸入頂點信息:"); 12 for ( i = 0; i < graph->vertex; i++ ) 13 { 14 scanf("%c", &graph->vertexs[i].info); 15 graph->vertexs[i].next = NULL; 16 getchar(); 17 } 18 19 for ( i = 0; i < graph->vertex; i++ ) 20 { 21 printf("輸入與節點%c相鄰的節點和權值,#號鍵結束\n", graph->vertexs[i].info); 22 for ( j = 0; j < graph->vertex; j++ ) 23 { 24 scanf("%c", &c); 25 if ( c == '#' ) 26 { 27 getchar(); 28 break; 29 } 30 scanf("%d", &num); 31 getchar(); 32 for ( k = 0; k < graph->vertex; k++ ) 33 { 34 if ( graph->vertexs[k].info != c ) 35 continue; 36 if ( graph->vertexs[k].next == NULL ) 37 graph->vertexs[k].next = make_node(i, num); 38 else 39 { 40 tmp = graph->vertexs[k].next; 41 while ( tmp->next != NULL ) 42 tmp = tmp->next; 43 tmp->next = make_node(i, num); 44 } 45 } 46 } 47 } 48 }
深度優先遍歷
鄰接表的深度優先遍歷根鄰接矩陣的差不多.只是由於數據的存儲方式有點差別,所以代碼實現會有些不同,但思路還是一樣的.
1 static void dfs_graph(Graph * graph, bool visited[], const int i); 2 void g_depth_first_search(Graph * graph) 3 { 4 bool visited[graph->vertex]; 5 int i; 6 7 for ( i = 0; i < graph->vertex; i++ ) 8 visited[i] = false; 9 10 visited[0] = true; 11 dfs_graph(graph, visited, 0); 12 } 13 14 static void dfs_graph(Graph * graph, bool visited[], const int i) 15 { 16 Arc_node * tmp; 17 printf("%c\t", graph->vertexs[i].info); 18 19 tmp = graph->vertexs[i].next; 20 while ( tmp != NULL ) 21 { 22 if ( !visited[tmp->pos] ) 23 { 24 visited[tmp->pos] = true; 25 dfs_graph(graph, visited, tmp->pos); 26 } 27 tmp = tmp->next; 28 } 29 }
廣度優先遍歷
1 void g_breadth_first_search(Graph * graph) 2 { 3 Queue queue; 4 bool visited[graph->vertex]; 5 int pos; 6 int i; 7 Arc_node * tmp; 8 9 q_init(&queue); 10 for ( i = 0; i < graph->vertex; i++ ) 11 visited[i] = false; 12 13 visited[0] = true; 14 q_push(&queue, 0); 15 while ( !q_empty(&queue) ) 16 { 17 pos = q_front(&queue); 18 printf("%c\t", graph->vertexs[pos].info); 19 tmp = graph->vertexs[pos].next; 20 while ( tmp != NULL ) 21 { 22 if ( !visited[tmp->pos] ) 23 { 24 visited[tmp->pos] = true; 25 q_push(&queue, tmp->pos); 26 } 27 tmp = tmp->next; 28 } 29 q_pop(&queue); 30 } 31 printf("\n"); 32 }
對於深度優先遍歷和廣度優先遍歷的算法思路不清楚的同學請先看鄰接矩陣.
graph.c
#include <stdio.h> #include <stdlib.h> #include "aqueue.h" #define MAX_NUM 100 typedef char node_type; typedef struct arc_node { int pos; int distance; struct arc_node * next; } Arc_node;//保存Node節點的相鄰節點信息 typedef struct node { node_type info; Arc_node * next; } Node;//保存節點信息 typedef struct graph { Node vertexs[MAX_NUM]; int vertex, arc; } Graph;//鄰接表 static Arc_node * make_node(const int pos, const int distance) { Arc_node * new_node = (Arc_node *)malloc( sizeof(Arc_node) ); if ( new_node == NULL ) exit(1); new_node->next = NULL; new_node->distance = distance; new_node->pos = pos; return new_node; } void g_create(Graph * graph) { int num; int i, j, k; char c; Arc_node * tmp; printf("輸入節點個數:"); scanf("%d", &graph->vertex); getchar(); printf("輸入頂點信息:"); for ( i = 0; i < graph->vertex; i++ ) { scanf("%c", &graph->vertexs[i].info); graph->vertexs[i].next = NULL; getchar(); } for ( i = 0; i < graph->vertex; i++ ) { printf("輸入與節點%c相鄰的節點和權值,#號鍵結束\n", graph->vertexs[i].info); for ( j = 0; j < graph->vertex; j++ ) { scanf("%c", &c); if ( c == '#' ) { getchar(); break; } scanf("%d", &num); getchar(); for ( k = 0; k < graph->vertex; k++ ) { if ( graph->vertexs[k].info != c ) continue; if ( graph->vertexs[k].next == NULL ) graph->vertexs[k].next = make_node(i, num); else { tmp = graph->vertexs[k].next; while ( tmp->next != NULL ) tmp = tmp->next; tmp->next = make_node(i, num); } } } } } static void dfs_graph(Graph * graph, bool visited[], const int i); void g_depth_first_search(Graph * graph) { bool visited[graph->vertex]; int i; for ( i = 0; i < graph->vertex; i++ ) visited[i] = false; visited[0] = true; dfs_graph(graph, visited, 0); } static void dfs_graph(Graph * graph, bool visited[], const int i) { Arc_node * tmp; printf("%c\t", graph->vertexs[i].info); tmp = graph->vertexs[i].next; while ( tmp != NULL ) { if ( !visited[tmp->pos] ) { visited[tmp->pos] = true; dfs_graph(graph, visited, tmp->pos); } tmp = tmp->next; } } void g_breadth_first_search(Graph * graph) { Queue queue; bool visited[graph->vertex]; int pos; int i; Arc_node * tmp; q_init(&queue); for ( i = 0; i < graph->vertex; i++ ) visited[i] = false; visited[0] = true; q_push(&queue, 0); while ( !q_empty(&queue) ) { pos = q_front(&queue); printf("%c\t", graph->vertexs[pos].info); tmp = graph->vertexs[pos].next; while ( tmp != NULL ) { if ( !visited[tmp->pos] ) { visited[tmp->pos] = true; q_push(&queue, tmp->pos); } tmp = tmp->next; } q_pop(&queue); } printf("\n"); } int main(void) { Graph graph; Arc_node * node; int i; g_create(&graph); for ( i = 0; i < graph.vertex; i++ ) { printf("%c\t", graph.vertexs[i].info); node = graph.vertexs[i].next; while ( node != NULL ) { printf("%d %d\t", node->distance, node->pos); node = node->next; } printf("\n"); } printf("\n"); g_depth_first_search(&graph); printf("\n"); g_breadth_first_search(&graph); return 0; }
