当前位置:   article > 正文

图的两种遍历:深度优先遍历+广度优先遍历_已知无向图采用邻接矩阵存储结构,编写程序,分别采用深度优先遍历和广度优先遍历方

已知无向图采用邻接矩阵存储结构,编写程序,分别采用深度优先遍历和广度优先遍历方

一、深度优先遍历

1、简介

深度优先遍历是指按照深度方向搜索,它类似于树的先根遍历,是树的先根遍历的推广。

基本思想(通俗)

选一条路走到 ,直到 走不通,就 原路返回看看 是否还有路可走,如果返回到起点还无路可走,说明深度优先遍历已完成。

2、举例说明

这是要深度遍历的无向图

 

 深度遍历依次访问的为:

v1->v2->v4->v8->v5->v3->v6->v7

3、C语言代码 

(1)邻接矩阵存储无向图。

12345678
101100000
210011000
310000110
401000001
501000001
600100000
700100000
800011000

对于图的存储,请参考我的文章:图的三种存储结构:邻接矩阵表示法+链表法+十字链表法

存储无向图

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define MAX_VERTEM_NUM 10
  4. #define INFINITY 32768
  5. typedef enum{
  6. DG,DN,UDG,UDN
  7. }graghKind;
  8. //digraph DG有向图
  9. //directed network DN有向网
  10. //undirected graph UDG无向图
  11. //undirected network UDN无向网
  12. typedef char vertemData;
  13. typedef struct {
  14. vertemData vert[MAX_VERTEM_NUM]; //顶点向量
  15. int adj[MAX_VERTEM_NUM][MAX_VERTEM_NUM]; //邻接矩阵
  16. int vertNum,arcNum; //图的顶点数和弧数
  17. graghKind gragh; //图的类型
  18. }adjMatrix;
  19. //求顶点位置
  20. int locateVertem(adjMatrix *G,vertemData v){
  21. for(int j=0;j<G->vertNum;j++)
  22. {
  23. if(G->vert[j]==v)
  24. {
  25. return j;
  26. }
  27. }
  28. }
  29. //创建无向图
  30. int creatUDG(adjMatrix *G){
  31. int i,j,k,weight;
  32. vertemData v1,v2;
  33. printf("请输入图的顶点数和弧数:\n");
  34. scanf("%d %d",&G->vertNum,&G->arcNum);
  35. for(i=0;i<G->vertNum;i++)
  36. for(j=0;j<G->vertNum;j++)
  37. G->adj[i][j] = 0;
  38. for(i=0;i<G->vertNum;i++)
  39. {
  40. printf("请输入图的顶点%d:\n",i);
  41. getchar();
  42. scanf("%c",&G->vert[i]);
  43. }
  44. for(k=0;k<G->arcNum;k++){
  45. printf("请输入弧%d的两个顶点:\n",k);
  46. getchar();
  47. scanf("%c %c",&v1,&v2);
  48. i = locateVertem(G,v1);
  49. j = locateVertem(G,v2);
  50. G->adj[i][j] = 1;
  51. G->adj[j][i] = 1;
  52. }
  53. printf("\n无向图存储完毕!\n\n");
  54. return 0;
  55. }

运行结果

(2) 用一个数组去存储已访问点的信息

01234567
00000000

0代表该点未访问,1代表该点访问了。

(3)深度遍历的算法描述

  • 更新访问点数组信息,在邻接矩阵当中找到该访问点的最近的邻接点,访问该邻接点,输出遍历顶点信息,重复此步骤。
  • 当无法继续深度遍历的时候,在访问点数组中往后依次退1,直到能有一个顶点能继续深度遍历。
  • 当起点都无法继续深度遍历的时候,对图的深度遍历已完成

实际就是从第n个顶点开始、标记该顶点已被访问,然后查找该顶点第一个未访问的邻接点第i个顶点,再去第i个顶点 深度遍历。

实际就是一个递归的过程。

  1. //深度遍历无向图
  2. void depth_first_traversal_UDG(adjMatrix *G,int *v,int n)
  3. {
  4. int i;
  5. if(G==NULL) return;
  6. if(n<0||n>G->vertNum) return;
  7. v[n] = 1;
  8. if(n==0) printf("%c",G->vert[n]);
  9. else printf("->%c",G->vert[n]);
  10. for(i=0;i<G->vertNum;i++)
  11. if(G->adj[n][i]!=0&&v[i]!=1) depth_first_traversal_UDG(G,v,i);
  12. }

(4)完整代码 

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define MAX_VERTEM_NUM 10
  4. #define INFINITY 32768
  5. typedef enum{
  6. DG,DN,UDG,UDN
  7. }graghKind;
  8. //digraph DG有向图
  9. //directed network DN有向网
  10. //undirected graph UDG无向图
  11. //undirected network UDN无向网
  12. typedef char vertemData;
  13. typedef struct {
  14. vertemData vert[MAX_VERTEM_NUM]; //顶点向量
  15. int adj[MAX_VERTEM_NUM][MAX_VERTEM_NUM]; //邻接矩阵
  16. int vertNum,arcNum; //图的顶点数和弧数
  17. graghKind gragh; //图的类型
  18. }adjMatrix;
  19. //求顶点位置
  20. int locateVertem(adjMatrix *G,vertemData v){
  21. for(int j=0;j<G->vertNum;j++)
  22. {
  23. if(G->vert[j]==v)
  24. {
  25. return j;
  26. }
  27. }
  28. }
  29. //创建无向图
  30. int creatUDG(adjMatrix *G){
  31. int i,j,k,weight;
  32. vertemData v1,v2;
  33. printf("请输入图的顶点数和弧数:\n");
  34. scanf("%d %d",&G->vertNum,&G->arcNum);
  35. for(i=0;i<G->vertNum;i++)
  36. for(j=0;j<G->vertNum;j++)
  37. G->adj[i][j] = 0;
  38. for(i=0;i<G->vertNum;i++)
  39. {
  40. printf("请输入图的顶点%d:\n",i);
  41. getchar();
  42. scanf("%c",&G->vert[i]);
  43. }
  44. for(k=0;k<G->arcNum;k++){
  45. printf("请输入弧%d的两个顶点:\n",k);
  46. getchar();
  47. scanf("%c %c",&v1,&v2);
  48. i = locateVertem(G,v1);
  49. j = locateVertem(G,v2);
  50. G->adj[i][j] = 1;
  51. G->adj[j][i] = 1;
  52. }
  53. printf("\n无向图存储完毕!\n\n");
  54. return 0;
  55. }
  56. //深度遍历无向图
  57. void depth_first_traversal_UDG(adjMatrix *G,int *v,int n)
  58. {
  59. int i;
  60. if(G==NULL) return;
  61. if(n<0||n>G->vertNum) return;
  62. v[n] = 1;
  63. if(n==0) printf("%c",G->vert[n]);
  64. else printf("->%c",G->vert[n]);
  65. for(i=0;i<G->vertNum;i++)
  66. if(G->adj[n][i]!=0&&v[i]!=1) depth_first_traversal_UDG(G,v,i);
  67. }
  68. int main(){
  69. adjMatrix *G = (adjMatrix*)malloc(sizeof(adjMatrix));
  70. creatUDG(G);
  71. int visited[G->vertNum]={0};
  72. printf("深度优先遍历无向图:\n");
  73. depth_first_traversal_UDG(G,visited,0);
  74. return 0;
  75. }

运行结果

 附

二、广度优先遍历

1、简介

广度优先搜索是指按照广度方向搜索,它类似于树的按层次遍历,是树的按层次遍历的推广。

基本思想(通俗)

把一层的邻接点访问完后再去访问下一层。

2、举例说明

这是要广度遍历的无向图

无向图进行广度优先遍历:

v1->v2->v3->v4->v5->v6->v7->v8 

3、C语言代码

(1)算法描述

当访问到n层的时候,依次入队列,出队列的顶点访问其邻接点并入队列。

广度遍历上图的情况下队列的变化如下:

  1. 1
  2. 2 3
  3. 3 4 5
  4. 4 5 6 7
  5. 5 6 7 8
  6. 6 7 8
  7. 7 8
  8. 8

(2)完整代码

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define MAX_VERTEM_NUM 10
  4. typedef enum{
  5. DG,DN,UDG,UDN
  6. }graghKind;
  7. //digraph DG有向图
  8. //directed network DN有向网
  9. //undirected graph UDG无向图
  10. //undirected network UDN无向网
  11. typedef char vertemData;
  12. int visited[MAX_VERTEM_NUM] = {0};//访问数组
  13. /*邻接矩阵*/
  14. typedef struct {
  15. vertemData vert[MAX_VERTEM_NUM]; //顶点向量
  16. int adj[MAX_VERTEM_NUM][MAX_VERTEM_NUM]; //邻接矩阵
  17. int vertNum,arcNum; //图的顶点数和弧数
  18. graghKind gragh; //图的类型
  19. }adjMatrix;
  20. /*队列结构*/
  21. typedef struct QNode
  22. {
  23. vertemData data;
  24. struct QNode *next;
  25. }QNode;
  26. typedef struct
  27. {
  28. QNode *front,*rear; //队头队尾指针
  29. }LinkQueue;
  30. /*求顶点位置*/
  31. int locateVertem(adjMatrix *G,vertemData v){
  32. for(int j=0;j<G->vertNum;j++)
  33. {
  34. if(G->vert[j]==v)
  35. {
  36. return j;
  37. }
  38. }
  39. }
  40. /*创建无向图*/
  41. int creatUDG(adjMatrix *G){
  42. int i,j,k,weight;
  43. vertemData v1,v2;
  44. printf("请输入图的顶点数和弧数:\n");
  45. scanf("%d %d",&G->vertNum,&G->arcNum);
  46. for(i=0;i<G->vertNum;i++)
  47. for(j=0;j<G->vertNum;j++)
  48. G->adj[i][j] = 0;
  49. for(i=0;i<G->vertNum;i++)
  50. {
  51. printf("请输入图的顶点%d:\n",i);
  52. getchar();
  53. scanf("%c",&G->vert[i]);
  54. }
  55. for(k=0;k<G->arcNum;k++){
  56. printf("请输入弧%d的两个顶点:\n",k);
  57. getchar();
  58. scanf("%c %c",&v1,&v2);
  59. i = locateVertem(G,v1);
  60. j = locateVertem(G,v2);
  61. G->adj[i][j] = 1;
  62. G->adj[j][i] = 1;
  63. }
  64. printf("\n无向图存储完毕!\n\n");
  65. return 0;
  66. }
  67. /*创建空队列*/
  68. int init_queue(LinkQueue *L)
  69. {
  70. L->front=L->rear=(QNode*)malloc(sizeof(QNode));
  71. if(!L->front) return 0;
  72. L->front->next=NULL;
  73. return 0;
  74. }
  75. /*判断队列是否为空*/
  76. int empty_queue(LinkQueue *L)
  77. {
  78. if(L->front->next==NULL) return 1;
  79. else return 0;
  80. }
  81. /*入队列*/
  82. int in_queue(LinkQueue *L,int n)
  83. {
  84. QNode *t = (QNode*)malloc(sizeof(QNode));
  85. if(!t) exit(0);
  86. t->data = n;
  87. t->next = NULL;
  88. L->rear->next = t;
  89. L->rear = t;
  90. free(t);
  91. return 0;
  92. }
  93. /*出队列*/
  94. int out_queue(LinkQueue *L)
  95. {
  96. QNode *t;
  97. if(L->front==L->rear) return 0;
  98. t = L->front->next;
  99. L->front->next = t->next;
  100. if(t==L->rear) L->rear = L->front;
  101. return 1;
  102. }
  103. /*广度遍历*/
  104. int BFS_traverse_UDN(adjMatrix *G)
  105. {
  106. int i=0,j;
  107. LinkQueue *L = (LinkQueue*)malloc(sizeof(LinkQueue));
  108. init_queue(L);
  109. printf("广度遍历无向图:");
  110. visited[i] = 1;
  111. printf("%c",G->vert[i]);
  112. in_queue(L,i);
  113. do
  114. {
  115. out_queue(L);
  116. for(j=0;j<G->vertNum;j++)
  117. {
  118. if(G->adj[i][j]!=0&&visited[j]!=1)
  119. {
  120. visited[j] = 1;
  121. printf("->%c",G->vert[j]);
  122. in_queue(L,j);
  123. }
  124. }
  125. i++;
  126. }while(!empty_queue(L));
  127. free(L);
  128. return 0;
  129. }
  130. int main()
  131. {
  132. adjMatrix *G = (adjMatrix*)malloc(sizeof(adjMatrix));
  133. creatUDG(G);
  134. BFS_traverse_UDN(G);
  135. return 0;
  136. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/509742
推荐阅读
相关标签
  

闽ICP备14008679号