图算法(一)

      图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 }

 

你可能感兴趣的:(图算法(一))