鱼C论坛

 找回密码
 立即注册
查看: 4039|回复: 1

[技术交流] 图的遍历完整代码(邻接矩阵)

[复制链接]
发表于 2016-3-9 02:07:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
邻接矩阵(无向图)

  1. /**
  2. * C: 邻接矩阵图表示的"无向图(Matrix Undirected Graph)"
  3. *
  4. * @author skywang
  5. * @date 2014/04/18
  6. */

  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <malloc.h>
  10. #include <string.h>

  11. #define MAX 100
  12. #define isLetter(a)  ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))
  13. #define LENGTH(a)  (sizeof(a)/sizeof(a[0]))

  14. // 邻接矩阵
  15. typedef struct _graph
  16. {
  17.     char vexs[MAX];       // 顶点集合
  18.     int vexnum;           // 顶点数
  19.     int edgnum;           // 边数
  20.     int matrix[MAX][MAX]; // 邻接矩阵
  21. }Graph, *PGraph;

  22. /*
  23. * 返回ch在matrix矩阵中的位置
  24. */
  25. static int get_position(Graph g, char ch)
  26. {
  27.     int i;
  28.     for(i=0; i<g.vexnum; i++)
  29.         if(g.vexs[i]==ch)
  30.             return i;
  31.     return -1;
  32. }

  33. /*
  34. * 读取一个输入字符
  35. */
  36. static char read_char()
  37. {
  38.     char ch;

  39.     do {
  40.         ch = getchar();
  41.     } while(!isLetter(ch));

  42.     return ch;
  43. }

  44. /*
  45. * 创建图(自己输入)
  46. */
  47. Graph* create_graph()
  48. {
  49.     char c1, c2;
  50.     int v, e;
  51.     int i, p1, p2;
  52.     Graph* pG;
  53.    
  54.     // 输入"顶点数"和"边数"
  55.     printf("input vertex number: ");
  56.     scanf("%d", &v);
  57.     printf("input edge number: ");
  58.     scanf("%d", &e);
  59.     if ( v < 1 || e < 1 || (e > (v * (v-1))))
  60.     {
  61.         printf("input error: invalid parameters!\n");
  62.         return NULL;
  63.     }
  64.    
  65.     if ((pG=(Graph*)malloc(sizeof(Graph))) == NULL )
  66.         return NULL;
  67.     memset(pG, 0, sizeof(Graph));

  68.     // 初始化"顶点数"和"边数"
  69.     pG->vexnum = v;
  70.     pG->edgnum = e;
  71.     // 初始化"顶点"
  72.     for (i = 0; i < pG->vexnum; i++)
  73.     {
  74.         printf("vertex(%d): ", i);
  75.         pG->vexs[i] = read_char();
  76.     }

  77.     // 初始化"边"
  78.     for (i = 0; i < pG->edgnum; i++)
  79.     {
  80.         // 读取边的起始顶点和结束顶点
  81.         printf("edge(%d):", i);
  82.         c1 = read_char();
  83.         c2 = read_char();

  84.         p1 = get_position(*pG, c1);
  85.         p2 = get_position(*pG, c2);
  86.         if (p1==-1 || p2==-1)
  87.         {
  88.             printf("input error: invalid edge!\n");
  89.             free(pG);
  90.             return NULL;
  91.         }

  92.         pG->matrix[p1][p2] = 1;
  93.         pG->matrix[p2][p1] = 1;
  94.     }

  95.     return pG;
  96. }

  97. /*
  98. * 创建图(用已提供的矩阵)
  99. */
  100. Graph* create_example_graph()
  101. {
  102.     char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
  103.     char edges[][2] = {
  104.         {'A', 'C'},
  105.         {'A', 'D'},
  106.         {'A', 'F'},
  107.         {'B', 'C'},
  108.         {'C', 'D'},
  109.         {'E', 'G'},
  110.         {'F', 'G'}};
  111.     int vlen = LENGTH(vexs);
  112.     int elen = LENGTH(edges);
  113.     int i, p1, p2;
  114.     Graph* pG;
  115.    
  116.     // 输入"顶点数"和"边数"
  117.     if ((pG=(Graph*)malloc(sizeof(Graph))) == NULL )
  118.         return NULL;
  119.     memset(pG, 0, sizeof(Graph));

  120.     // 初始化"顶点数"和"边数"
  121.     pG->vexnum = vlen;
  122.     pG->edgnum = elen;
  123.     // 初始化"顶点"
  124.     for (i = 0; i < pG->vexnum; i++)
  125.     {
  126.         pG->vexs[i] = vexs[i];
  127.     }

  128.     // 初始化"边"
  129.     for (i = 0; i < pG->edgnum; i++)
  130.     {
  131.         // 读取边的起始顶点和结束顶点
  132.         p1 = get_position(*pG, edges[i][0]);
  133.         p2 = get_position(*pG, edges[i][1]);

  134.         pG->matrix[p1][p2] = 1;
  135.         pG->matrix[p2][p1] = 1;
  136.     }

  137.     return pG;
  138. }

  139. /*
  140. * 返回顶点v的第一个邻接顶点的索引,失败则返回-1
  141. */
  142. static int first_vertex(Graph G, int v)
  143. {
  144.     int i;

  145.     if (v<0 || v>(G.vexnum-1))
  146.         return -1;

  147.     for (i = 0; i < G.vexnum; i++)
  148.         if (G.matrix[v][i] == 1)
  149.             return i;

  150.     return -1;
  151. }

  152. /*
  153. * 返回顶点v相对于w的下一个邻接顶点的索引,失败则返回-1
  154. */
  155. static int next_vertix(Graph G, int v, int w)
  156. {
  157.     int i;

  158.     if (v<0 || v>(G.vexnum-1) || w<0 || w>(G.vexnum-1))
  159.         return -1;

  160.     for (i = w + 1; i < G.vexnum; i++)
  161.         if (G.matrix[v][i] == 1)
  162.             return i;

  163.     return -1;
  164. }

  165. /*
  166. * 深度优先搜索遍历图的递归实现
  167. */
  168. static void DFS(Graph G, int i, int *visited)
  169. {                                   
  170.     int w;

  171.     visited[i] = 1;
  172.     printf("%c ", G.vexs[i]);
  173.     // 遍历该顶点的所有邻接顶点。若是没有访问过,那么继续往下走
  174.     for (w = first_vertex(G, i); w >= 0; w = next_vertix(G, i, w))
  175.     {
  176.         if (!visited[w])
  177.             DFS(G, w, visited);
  178.     }
  179.       
  180. }

  181. /*
  182. * 深度优先搜索遍历图
  183. */
  184. void DFSTraverse(Graph G)
  185. {
  186.     int i;
  187.     int visited[MAX];       // 顶点访问标记

  188.     // 初始化所有顶点都没有被访问
  189.     for (i = 0; i < G.vexnum; i++)
  190.         visited[i] = 0;

  191.     printf("DFS: ");
  192.     for (i = 0; i < G.vexnum; i++)
  193.     {
  194.         //printf("\n== LOOP(%d)\n", i);
  195.         if (!visited[i])
  196.             DFS(G, i, visited);
  197.     }
  198.     printf("\n");
  199. }

  200. /*
  201. * 广度优先搜索(类似于树的层次遍历)
  202. */
  203. void BFS(Graph G)
  204. {
  205.     int head = 0;
  206.     int rear = 0;
  207.     int queue[MAX];     // 辅组队列
  208.     int visited[MAX];   // 顶点访问标记
  209.     int i, j, k;

  210.     for (i = 0; i < G.vexnum; i++)
  211.         visited[i] = 0;

  212.     printf("BFS: ");
  213.     for (i = 0; i < G.vexnum; i++)
  214.     {
  215.         if (!visited[i])
  216.         {
  217.             visited[i] = 1;
  218.             printf("%c ", G.vexs[i]);
  219.             queue[rear++] = i;  // 入队列
  220.         }
  221.         while (head != rear)
  222.         {
  223.             j = queue[head++];  // 出队列
  224.             for (k = first_vertex(G, j); k >= 0; k = next_vertix(G, j, k)) //k是为访问的邻接顶点
  225.             {
  226.                 if (!visited[k])
  227.                 {
  228.                     visited[k] = 1;
  229.                     printf("%c ", G.vexs[k]);
  230.                     queue[rear++] = k;
  231.                 }
  232.             }
  233.         }
  234.     }
  235.     printf("\n");
  236. }

  237. /*
  238. * 打印矩阵队列图
  239. */
  240. void print_graph(Graph G)
  241. {
  242.     int i,j;

  243.     printf("Martix Graph:\n");
  244.     for (i = 0; i < G.vexnum; i++)
  245.     {
  246.         for (j = 0; j < G.vexnum; j++)
  247.             printf("%d ", G.matrix[i][j]);
  248.         printf("\n");
  249.     }
  250. }

  251. void main()
  252. {
  253.     Graph* pG;

  254.     // 自定义"图"(输入矩阵队列)
  255.     //pG = create_graph();
  256.     // 采用已有的"图"
  257.     pG = create_example_graph();

  258.     print_graph(*pG);       // 打印图
  259.     DFSTraverse(*pG);       // 深度优先遍历
  260.     BFS(*pG);               // 广度优先遍历
  261. }
复制代码


邻接矩阵(有向图)

  1. /**
  2. * C: 邻接矩阵表示的"有向图(Matrix Directed Graph)"
  3. *
  4. * @author skywang
  5. * @date 2014/04/18
  6. */

  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <malloc.h>
  10. #include <string.h>

  11. #define MAX 100
  12. #define isLetter(a)  ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))
  13. #define LENGTH(a)  (sizeof(a)/sizeof(a[0]))

  14. // 邻接矩阵
  15. typedef struct _graph
  16. {
  17.     char vexs[MAX];       // 顶点集合
  18.     int vexnum;           // 顶点数
  19.     int edgnum;           // 边数
  20.     int matrix[MAX][MAX]; // 邻接矩阵
  21. }Graph, *PGraph;

  22. /*
  23. * 返回ch在matrix矩阵中的位置
  24. */
  25. static int get_position(Graph g, char ch)
  26. {
  27.     int i;
  28.     for(i=0; i<g.vexnum; i++)
  29.         if(g.vexs[i]==ch)
  30.             return i;
  31.     return -1;
  32. }

  33. /*
  34. * 读取一个输入字符
  35. */
  36. static char read_char()
  37. {
  38.     char ch;

  39.     do {
  40.         ch = getchar();
  41.     } while(!isLetter(ch));

  42.     return ch;
  43. }

  44. /*
  45. * 创建图(自己输入)
  46. */
  47. Graph* create_graph()
  48. {
  49.     char c1, c2;
  50.     int v, e;
  51.     int i, p1, p2;
  52.     Graph* pG;
  53.    
  54.     // 输入"顶点数"和"边数"
  55.     printf("input vertex number: ");
  56.     scanf("%d", &v);
  57.     printf("input edge number: ");
  58.     scanf("%d", &e);
  59.     if ( v < 1 || e < 1 || (e > (v * (v-1))))
  60.     {
  61.         printf("input error: invalid parameters!\n");
  62.         return NULL;
  63.     }
  64.    
  65.     if ((pG=(Graph*)malloc(sizeof(Graph))) == NULL )
  66.         return NULL;
  67.     memset(pG, 0, sizeof(Graph));

  68.     // 初始化"顶点数"和"边数"
  69.     pG->vexnum = v;
  70.     pG->edgnum = e;
  71.     // 初始化"顶点"
  72.     for (i = 0; i < pG->vexnum; i++)
  73.     {
  74.         printf("vertex(%d): ", i);
  75.         pG->vexs[i] = read_char();
  76.     }

  77.     // 初始化"边"
  78.     for (i = 0; i < pG->edgnum; i++)
  79.     {
  80.         // 读取边的起始顶点和结束顶点
  81.         printf("edge(%d):", i);
  82.         c1 = read_char();
  83.         c2 = read_char();

  84.         p1 = get_position(*pG, c1);
  85.         p2 = get_position(*pG, c2);
  86.         if (p1==-1 || p2==-1)
  87.         {
  88.             printf("input error: invalid edge!\n");
  89.             free(pG);
  90.             return NULL;
  91.         }

  92.         pG->matrix[p1][p2] = 1;
  93.     }

  94.     return pG;
  95. }

  96. /*
  97. * 创建图(用已提供的矩阵)
  98. */
  99. Graph* create_example_graph()
  100. {
  101.     char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
  102.     char edges[][2] = {
  103.         {'A', 'B'},
  104.         {'B', 'C'},
  105.         {'B', 'E'},
  106.         {'B', 'F'},
  107.         {'C', 'E'},
  108.         {'D', 'C'},
  109.         {'E', 'B'},
  110.         {'E', 'D'},
  111.         {'F', 'G'}};
  112.     int vlen = LENGTH(vexs);
  113.     int elen = LENGTH(edges);
  114.     int i, p1, p2;
  115.     Graph* pG;
  116.    
  117.     // 输入"顶点数"和"边数"
  118.     if ((pG=(Graph*)malloc(sizeof(Graph))) == NULL )
  119.         return NULL;
  120.     memset(pG, 0, sizeof(Graph));

  121.     // 初始化"顶点数"和"边数"
  122.     pG->vexnum = vlen;
  123.     pG->edgnum = elen;
  124.     // 初始化"顶点"
  125.     for (i = 0; i < pG->vexnum; i++)
  126.     {
  127.         pG->vexs[i] = vexs[i];
  128.     }

  129.     // 初始化"边"
  130.     for (i = 0; i < pG->edgnum; i++)
  131.     {
  132.         // 读取边的起始顶点和结束顶点
  133.         p1 = get_position(*pG, edges[i][0]);
  134.         p2 = get_position(*pG, edges[i][1]);

  135.         pG->matrix[p1][p2] = 1;
  136.     }

  137.     return pG;
  138. }

  139. /*
  140. * 返回顶点v的第一个邻接顶点的索引,失败则返回-1
  141. */
  142. static int first_vertex(Graph G, int v)
  143. {
  144.     int i;

  145.     if (v<0 || v>(G.vexnum-1))
  146.         return -1;

  147.     for (i = 0; i < G.vexnum; i++)
  148.         if (G.matrix[v][i] == 1)
  149.             return i;

  150.     return -1;
  151. }

  152. /*
  153. * 返回顶点v相对于w的下一个邻接顶点的索引,失败则返回-1
  154. */
  155. static int next_vertix(Graph G, int v, int w)
  156. {
  157.     int i;

  158.     if (v<0 || v>(G.vexnum-1) || w<0 || w>(G.vexnum-1))
  159.         return -1;

  160.     for (i = w + 1; i < G.vexnum; i++)
  161.         if (G.matrix[v][i] == 1)
  162.             return i;

  163.     return -1;
  164. }

  165. /*
  166. * 深度优先搜索遍历图的递归实现
  167. */
  168. static void DFS(Graph G, int i, int *visited)
  169. {                                   
  170.     int w;

  171.     visited[i] = 1;
  172.     printf("%c ", G.vexs[i]);
  173.     // 遍历该顶点的所有邻接顶点。若是没有访问过,那么继续往下走
  174.     for (w = first_vertex(G, i); w >= 0; w = next_vertix(G, i, w))
  175.     {
  176.         if (!visited[w])
  177.             DFS(G, w, visited);
  178.     }
  179.       
  180. }

  181. /*
  182. * 深度优先搜索遍历图
  183. */
  184. void DFSTraverse(Graph G)
  185. {
  186.     int i;
  187.     int visited[MAX];       // 顶点访问标记

  188.     // 初始化所有顶点都没有被访问
  189.     for (i = 0; i < G.vexnum; i++)
  190.         visited[i] = 0;

  191.     printf("DFS: ");
  192.     for (i = 0; i < G.vexnum; i++)
  193.     {
  194.         //printf("\n== LOOP(%d)\n", i);
  195.         if (!visited[i])
  196.             DFS(G, i, visited);
  197.     }
  198.     printf("\n");
  199. }

  200. /*
  201. * 广度优先搜索(类似于树的层次遍历)
  202. */
  203. void BFS(Graph G)
  204. {
  205.     int head = 0;
  206.     int rear = 0;
  207.     int queue[MAX];     // 辅组队列
  208.     int visited[MAX];   // 顶点访问标记
  209.     int i, j, k;

  210.     for (i = 0; i < G.vexnum; i++)
  211.         visited[i] = 0;

  212.     printf("BFS: ");
  213.     for (i = 0; i < G.vexnum; i++)
  214.     {
  215.         if (!visited[i])
  216.         {
  217.             visited[i] = 1;
  218.             printf("%c ", G.vexs[i]);
  219.             queue[rear++] = i;  // 入队列
  220.         }
  221.         while (head != rear)
  222.         {
  223.             j = queue[head++];  // 出队列
  224.             for (k = first_vertex(G, j); k >= 0; k = next_vertix(G, j, k)) //k是为访问的邻接顶点
  225.             {
  226.                 if (!visited[k])
  227.                 {
  228.                     visited[k] = 1;
  229.                     printf("%c ", G.vexs[k]);
  230.                     queue[rear++] = k;
  231.                 }
  232.             }
  233.         }
  234.     }
  235.     printf("\n");
  236. }

  237. /*
  238. * 打印矩阵队列图
  239. */
  240. void print_graph(Graph G)
  241. {
  242.     int i,j;

  243.     printf("Martix Graph:\n");
  244.     for (i = 0; i < G.vexnum; i++)
  245.     {
  246.         for (j = 0; j < G.vexnum; j++)
  247.             printf("%d ", G.matrix[i][j]);
  248.         printf("\n");
  249.     }
  250. }

  251. void main()
  252. {
  253.     Graph* pG;

  254.     // 自定义"图"(输入矩阵队列)
  255.     //pG = create_graph();
  256.     // 采用已有的"图"
  257.     pG = create_example_graph();

  258.     print_graph(*pG);       // 打印图
  259.     DFSTraverse(*pG);       // 深度优先遍历
  260.     BFS(*pG);               // 广度优先遍历
  261. }
复制代码


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-4-4 16:49:26 | 显示全部楼层
题主辛苦啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 04:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表