zoukankan      html  css  js  c++  java
  • 图算法(一)

          图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("
    ");
    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 }
  • 相关阅读:
    Hibernate实体类注解
    Struts2注解详解
    Spring注解大全
    Maven依赖机制
    Maven启动代理服务器
    SSH整合
    二进制求和 —— 从复杂方法到简单方法
    最大子序和 —— 动态规划解法
    括号匹配问题 —— Deque双端队列解法
    常见面试题 —— 两数之和(拒绝暴利法)
  • 原文地址:https://www.cnblogs.com/ym65536/p/4400963.html
Copyright © 2011-2022 走看看