图G=(V, E)是由若干给定的顶点V及连接两顶点的边E所构成的图形,图论起源于柯尼斯堡七桥问题。
1、图的表示
邻接矩阵:表示简单,但是对于稀疏矩阵,浪费空间严重。
邻居表:相对于邻接矩阵,存储复制,稀疏矩阵情况下空间利用率高。以下用邻接表来存储图结构:
1 struct graph 2 { 3 int g_vertexs; 4 int g_edges; 5 struct vertex_node *list_head; 6 }; 7 8 struct vertex_node 9 { 10 int vertex; 11 int weight; 12 struct vector_node *next; 13 };
利用文件graph.ini初始化图:
graph.ini:
9 16 0 1 1 0 2 5 1 2 3 1 3 7 1 4 5 2 4 1 2 5 7 3 4 2 3 6 3 4 5 3 4 6 6 4 7 9 5 7 5 6 7 2 6 8 7 7 8 4
1 void graph_create(struct graph *G, int dir) 2 { 3 FILE *fp = fopen("graph.ini", "r"); 4 int i, first, second, weight; 5 struct vertex_node *node; 6 if (fp == NULL) 7 { 8 perror("fopen"); 9 return; 10 } 11 12 fscanf(fp, "%d %d", &G->g_vertexs, &G->g_edges); 13 G->list_head = (struct vertex_node *)malloc(sizeof(struct vertex_node) * G->g_vertexs); 14 for (i = 0; i < G->g_vertexs; i++) 15 { 16 G->list_head[i].vertex = i; 17 G->list_head[i].weight = 0; 18 G->list_head[i].next = NULL; 19 } 20 for (i = 0; i < G->g_edges; i++) 21 { 22 fscanf(fp, "%d %d %d", &first, &second, &weight); 23 node = (struct vertex_node *)malloc(sizeof(struct vertex_node)); 24 node->vertex = second; 25 node->weight = weight; 26 node->next = G->list_head[first].next; 27 G->list_head[first].next = node; 28 if (!dir) 29 { 30 node = (struct vertex_node *)malloc(sizeof(struct vertex_node)); 31 node->vertex = first; 32 node->weight = weight; 33 node->next = G->list_head[second].next; 34 G->list_head[second].next = node; 35 } 36 } 37 38 mark = (int *)malloc(sizeof(int) * G->g_vertexs); 39 sp = (int *)malloc(sizeof(int) * G->g_vertexs); 40 pre = (int *)malloc(sizeof(int) * G->g_vertexs); 41 path = (int *)malloc(sizeof(int) * G->g_vertexs); 42 }
图的删除
1 void graph_destroy(struct graph *G) 2 { 3 int i; 4 struct vertex_node *node; 5 for (i = 0; i < G->g_vertexs; i++) 6 { 7 printf("node = %d", G->list_head[i].vertex); 8 while (G->list_head[i].next != NULL) 9 { 10 node = G->list_head[i].next; 11 printf(" -> %d", node->vertex); 12 G->list_head[i].next = node->next; 13 free(node); 14 } 15 printf("\n"); 16 } 17 free(G->list_head); 18 free(mark); 19 free(sp); 20 free(pre); 21 free(path); 22 }
2. 图的遍历
深度优先遍历DFS
1 /* 递归遍历 */ 2 void dfs(struct graph *G, int vertex) 3 { 4 struct vertex_node *node; 5 mark[vertex] = 1; 6 printf("%d -> ", vertex); 7 for (node = G->list_head[vertex].next; node != NULL; node = node->next) 8 { 9 if (!mark[node->vertex]) 10 dfs(G, node->vertex); 11 } 12 }
1 /* 非递归遍历 */ 2 void dfs(struct graph *G, int vertex) 3 { 4 int i; 5 struct vertex_node *node; 6 for (i = 0; i < G->g_vertexs; i++) 7 mark[i] = WHITE; 8 push(vertex); 9 while (!stack_empty()) 10 { 11 vertex = pop(); 12 if (mark[vertex] != BLACK) 13 { 14 mark[vertex] = BLACK; 15 printf("%d -> ", vertex); 16 } 17 for (node = G->list_head[vertex].next; node != NULL; node = node->next) 18 { 19 if (mark[node->vertex] != BLACK) 20 { 21 push(node->vertex); 22 mark[node->vertex] = GRAY; 23 } 24 } 25 } 26 }
广度优先遍历BFS
1 void bfs(struct graph *G, int vertex) 2 { 3 struct vertex_node *node; 4 memset(mark, 0, sizeof(int) * G->g_vertexs); 5 enqueue(vertex); 6 while (!queue_empty()) 7 { 8 vertex = dequeue(); 9 mark[vertex] = 1; 10 printf("%d -> ", vertex); 11 for (node = G->list_head[vertex].next; node != NULL; node = node->next) 12 { 13 if (!mark[node->vertex]) 14 { 15 enqueue(node->vertex); 16 mark[node->vertex] = 1; 17 } 18 } 19 } 20 }
时间: 2024-10-24 23:29:25