鱼C论坛

 找回密码
 立即注册
查看: 1684|回复: 3

[C\C++] C语言实现图的遍历

[复制链接]
发表于 2024-6-5 23:31:07 | 显示全部楼层 |阅读模式
50鱼币

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define OVERFLOW -2
  8. typedef int Status;
  9. typedef struct Node
  10. {
  11.         int elem;
  12.         struct Node *next;
  13. }Node,*QNode;
  14. typedef struct
  15. {
  16.         QNode front;
  17.         QNode rear;
  18. }Queue;
  19. #define MAX 20

  20. typedef struct ArcNode       //表结点
  21. {
  22.         int adjvex;              //该边所指向的顶点的位置
  23.         struct ArcNode *nextarc; //指向下一条边
  24. }ArcNode;

  25. typedef struct VNode           //头结点
  26. {
  27.         int data;                //顶点信息
  28.         ArcNode *firstarc;       //指向第一条依附该结点的边的指针
  29. }VNode,AdjList[MAX];

  30. typedef struct
  31. {
  32.         AdjList vertices;     //一维数组(头结点)
  33.         int vexnum;           //结点的个数
  34.         int arcnum;           //边的条数
  35. }Graph;
  36. Queue* InitQueue(Queue *Q)
  37. {
  38.         Q->front=(QNode)malloc(sizeof(Node));
  39.         if(Q->front!=NULL)  
  40.         {
  41.                 Q->rear=Q->front;
  42.                 Q->front->next=NULL;
  43.                 return Q;
  44.         }

  45.         else return NULL;
  46. }
  47. Status EnQueue(Queue *Q,int e)
  48. {
  49.        
  50.         QNode newnode;
  51.         newnode=(QNode)malloc(sizeof(Node));
  52.         if(newnode!=NULL)
  53.         {
  54.                 newnode->elem=e;
  55.                 newnode->next=NULL;
  56.                 Q->rear->next=newnode;
  57.                 Q->rear=newnode;
  58.                 return OK;
  59.         }
  60.         else return FALSE;
  61. }
  62. Status DeQueue(Queue *Q,int *e)
  63. {
  64.         QNode p;
  65.         if(Q->front==Q->rear)
  66.         {
  67.                 return 0;
  68.         }
  69.         p=Q->front->next;
  70.         Q->front->next=p->next;
  71.         if(Q->rear==p)
  72.                 Q->rear=Q->front;
  73.         *e=p->elem;
  74.         free(p);
  75.         return 1;
  76. }

  77. int LocateVex(Graph *G,int index)
  78. {
  79.         int i;
  80.         for(i=0;i<G->vexnum;i++)
  81.         {
  82.                 if(G->vertices[i].data==index)
  83.                         return i;
  84.         }
  85. }

  86. Status CreateGraph(Graph *G)//Status CreateGraph(Graph &G)(引用参数)
  87. {//以邻接表形式创建无向图G
  88.         int m,n,i,j,k,v1,v2,flag=0;
  89.         ArcNode *p1,*q1,*p,*q;
  90.         printf("请输入VNode的编号: ");
  91.         scanf("%d",&m);
  92.         printf("请输入ArcNode的编号");
  93.         scanf("%d",&n);
  94.         G->vexnum=m;            //顶点数目
  95.         G->arcnum=n;            //边的数目
  96.         for(i=0;i<G->vexnum;++i)
  97.         {
  98.                 G->vertices[i].data=i+1;      //顶点信息
  99.                 G->vertices[i].firstarc=NULL;
  100.         }
  101.         //顶点信息
  102.         printf("输出VNode的消息:\n");
  103.         for(i=0;i<G->vexnum;++i)
  104.                 printf("v%d\n",G->vertices[i].data);
  105.        
  106.         for(k=0;k<G->arcnum;++k)
  107.         {
  108.                 printf("请输入%d边起始点和端点: ",k+1);
  109.                 scanf("%d%d",&v1,&v2);
  110.                 i=LocateVex(G,v1);
  111.                 j=LocateVex(G,v2);
  112.                
  113.                 if(i>=0&&j>=0)
  114.                 {
  115.                         ++flag;
  116.                         p=(ArcNode *)malloc(sizeof(ArcNode));
  117.                         p->adjvex=j;
  118.                         p->nextarc=NULL;
  119.                         if(!G->vertices[i].firstarc)
  120.                                 G->vertices[i].firstarc=p;
  121.                         else
  122.                         {
  123.                                 for(p1=G->vertices[i].firstarc;p1->nextarc;p1=p1->nextarc);
  124.                                 p1->nextarc=p;
  125.                         }
  126.                        
  127.                         q=(ArcNode *)malloc(sizeof(ArcNode));
  128.                         q->adjvex=i;
  129.                         q->nextarc=NULL;
  130.                         if(!G->vertices[j].firstarc)
  131.                                 G->vertices[j].firstarc=q;
  132.                         else
  133.                         {
  134.                                 for(q1=G->vertices[j].firstarc;q1->nextarc;q1=q1->nextarc);
  135.                                 q1->nextarc=q;
  136.                         }
  137.                 }
  138.                 else
  139.                 {
  140.                         printf("没有这个优势!\n");
  141.                         k=flag-1;
  142.                 }
  143.                
  144.         }
  145.        
  146.         printf("邻接表为:\n"); //输出邻接表
  147.         for(i=0;i<G->vexnum;++i)
  148.         {
  149.                 printf("\t%d v%d->",i,G->vertices[i].data);
  150.                 p=G->vertices[i].firstarc;
  151.                 while(p->nextarc)
  152.                 {
  153.                         printf("%d->",p->adjvex);
  154.                         p=p->nextarc;
  155.                 }
  156.                 printf("%d\n",p->adjvex);
  157.         }
  158.         return OK;
  159. }

  160. int FirstAdjVex(Graph G,int v)
  161. {//返回v的第一个邻接顶点
  162.         ArcNode *p;
  163.         p=G.vertices[v].firstarc;
  164.         if(p)
  165.                 return (p->adjvex);
  166.         else
  167.                 return -1;
  168. }


  169. int NextAdjVex(Graph G,int v,int w)
  170. {//返回v中相对于w的下一个邻接顶点
  171.         int flag=0;
  172.         ArcNode *p;
  173.         p=G.vertices[v].firstarc;
  174.         while(p)
  175.         {
  176.                 if(p->adjvex==w)
  177.                 {
  178.                         flag=1;
  179.                         break;
  180.                 }
  181.                 p=p->nextarc;
  182.         }
  183.         if(flag && p->nextarc)
  184.                 return p->nextarc->adjvex;
  185.         else
  186.                 return -1;
  187. }

  188. int Visited[MAX];

  189. void DFS(Graph G,int v)
  190. {//深度优先遍历
  191.        
  192.         ArcNode *p;
  193.         p=G.vertices[v].firstarc;
  194.         printf("%d ",G.vertices[v].data);
  195.         Visited[v]=TRUE;
  196.         while(p)
  197.         {
  198.                 if(!Visited[p->adjvex])
  199.                 {
  200.                
  201.                         DFS(G,p->adjvex);
  202.                 }
  203.                 p=p->nextarc;
  204.                
  205.         }
  206. }

  207. void DFSTraverse(Graph G)
  208. {
  209.         int i;//递归
  210.         for(i=0;i<G.vexnum;i++)
  211.         {
  212.                 Visited[i]=FALSE;
  213.         }
  214.         for(i=0;i<G.vexnum;i++)
  215.         {
  216.                 if(!Visited[i])
  217.                         DFS(G,i);
  218.         }
  219. }

  220. void BFSTraverse(Graph G)
  221. {//广度优先遍历
  222.         int i,index;
  223.         ArcNode *temp;
  224.         Queue* que=InitQueue(que);
  225.        
  226.         for(i=0;i<G.vexnum;i++)
  227.         {
  228.                 Visited[i]=0;
  229.         }
  230.         index=G.vertices[0].data;
  231.         if(!Visited[index])
  232.         {
  233.                 EnQueue(que,index);
  234.                 Visited[index]=1;
  235.                 while(que->rear!=que->front)
  236.                 {
  237.                         DeQueue(que,&index);
  238.                        
  239.                         printf("%d ",G.vertices[index].data);
  240.                         temp=G.vertices[index].firstarc;
  241.                         while(temp)
  242.                         {
  243.                                 index=LocateVex(&G,G.vertices[index].data);
  244.                                 if(!Visited[index])
  245.                                 {
  246.                                         EnQueue(que,index);
  247.                                         Visited[index]=1;
  248.                                 }
  249.                                 temp=temp->nextarc;
  250.                                
  251.                         }
  252.                 }
  253.         }
  254.        
  255. }

  256. void main()
  257.                         {
  258.                                 Graph G;
  259.                                 CreateGraph(&G);
  260.                                 printf("深度优先搜索:\n");
  261.                                 DFSTraverse(G);
  262.                                 printf("\n广度优先搜索:\n");
  263.                                 BFSTraverse(G);
  264.                                 printf("\n");
  265.                                 system("pause");
  266.                         }
  267.                        
  268.        
  269.                        
  270.                        
复制代码

能不能帮忙看看为什么广度遍历不成功啊,急
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-6-5 23:31:08 | 显示全部楼层
本帖最后由 小甲鱼的二师兄 于 2024-6-5 23:45 编辑
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define OVERFLOW -2

  8. typedef int Status;

  9. typedef struct Node {
  10.     int elem;
  11.     struct Node *next;
  12. } Node, *QNode;

  13. typedef struct {
  14.     QNode front;
  15.     QNode rear;
  16. } Queue;

  17. #define MAX 20

  18. typedef struct ArcNode {       // 表结点
  19.     int adjvex;                // 该边所指向的顶点的位置
  20.     struct ArcNode *nextarc;   // 指向下一条边
  21. } ArcNode;

  22. typedef struct VNode {         // 头结点
  23.     int data;                  // 顶点信息
  24.     ArcNode *firstarc;         // 指向第一条依附该结点的边的指针
  25. } VNode, AdjList[MAX];

  26. typedef struct {
  27.     AdjList vertices;          // 一维数组(头结点)
  28.     int vexnum;                // 结点的个数
  29.     int arcnum;                // 边的条数
  30. } Graph;

  31. // 初始化队列
  32. Queue* InitQueue(Queue *Q) {
  33.     Q->front = (QNode)malloc(sizeof(Node));
  34.     if (Q->front != NULL) {
  35.         Q->rear = Q->front;
  36.         Q->front->next = NULL;
  37.         return Q;
  38.     } else {
  39.         return NULL;
  40.     }
  41. }

  42. // 入队
  43. Status EnQueue(Queue *Q, int e) {
  44.     QNode newnode;
  45.     newnode = (QNode)malloc(sizeof(Node));
  46.     if (newnode != NULL) {
  47.         newnode->elem = e;
  48.         newnode->next = NULL;
  49.         Q->rear->next = newnode;
  50.         Q->rear = newnode;
  51.         return OK;
  52.     } else {
  53.         return FALSE;
  54.     }
  55. }

  56. // 出队
  57. Status DeQueue(Queue *Q, int *e) {
  58.     QNode p;
  59.     if (Q->front == Q->rear) {
  60.         return 0;
  61.     }
  62.     p = Q->front->next;
  63.     Q->front->next = p->next;
  64.     if (Q->rear == p) {
  65.         Q->rear = Q->front;
  66.     }
  67.     *e = p->elem;
  68.     free(p);
  69.     return 1;
  70. }

  71. // 查找顶点位置
  72. int LocateVex(Graph *G, int index) {
  73.     int i;
  74.     for (i = 0; i < G->vexnum; i++) {
  75.         if (G->vertices[i].data == index)
  76.             return i;
  77.     }
  78.     return -1;  // 如果找不到顶点,返回-1
  79. }

  80. // 创建图
  81. Status CreateGraph(Graph *G) {
  82.     int m, n, i, j, k, v1, v2;
  83.     ArcNode *p1, *q1, *p, *q;
  84.     printf("请输入VNode的编号: ");
  85.     scanf("%d", &m);
  86.     printf("请输入ArcNode的编号: ");
  87.     scanf("%d", &n);
  88.     G->vexnum = m;            // 顶点数目
  89.     G->arcnum = n;            // 边的数目

  90.     for (i = 0; i < G->vexnum; ++i) {
  91.         G->vertices[i].data = i + 1;      // 顶点信息
  92.         G->vertices[i].firstarc = NULL;
  93.     }

  94.     printf("输出VNode的信息:\n");
  95.     for (i = 0; i < G->vexnum; ++i)
  96.         printf("v%d\n", G->vertices[i].data);

  97.     for (k = 0; k < G->arcnum; ++k) {
  98.         printf("请输入第%d条边的起始点和终点: ", k + 1);
  99.         scanf("%d%d", &v1, &v2);
  100.         i = LocateVex(G, v1);
  101.         j = LocateVex(G, v2);

  102.         if (i >= 0 && j >= 0) {
  103.             p = (ArcNode *)malloc(sizeof(ArcNode));
  104.             p->adjvex = j;
  105.             p->nextarc = NULL;
  106.             if (!G->vertices[i].firstarc)
  107.                 G->vertices[i].firstarc = p;
  108.             else {
  109.                 for (p1 = G->vertices[i].firstarc; p1->nextarc; p1 = p1->nextarc);
  110.                 p1->nextarc = p;
  111.             }

  112.             q = (ArcNode *)malloc(sizeof(ArcNode));
  113.             q->adjvex = i;
  114.             q->nextarc = NULL;
  115.             if (!G->vertices[j].firstarc)
  116.                 G->vertices[j].firstarc = q;
  117.             else {
  118.                 for (q1 = G->vertices[j].firstarc; q1->nextarc; q1 = q1->nextarc);
  119.                 q1->nextarc = q;
  120.             }
  121.         } else {
  122.             printf("没有这个顶点!\n");
  123.             --k;  // 如果顶点不存在,重新输入这条边
  124.         }
  125.     }

  126.     printf("邻接表为:\n");  // 输出邻接表
  127.     for (i = 0; i < G->vexnum; ++i) {
  128.         printf("\t%d v%d->", i, G->vertices[i].data);
  129.         p = G->vertices[i].firstarc;
  130.         while (p) {
  131.             printf("%d->", p->adjvex);
  132.             p = p->nextarc;
  133.         }
  134.         printf("NULL\n");
  135.     }
  136.     return OK;
  137. }

  138. int Visited[MAX];  // 访问标志数组

  139. // 广度优先遍历
  140. void BFSTraverse(Graph G) {
  141.     int i, index;
  142.     ArcNode *temp;
  143.     Queue que;
  144.     InitQueue(&que);

  145.     for (i = 0; i < G.vexnum; i++) {
  146.         Visited[i] = 0;  // 初始化访问标志数组
  147.     }

  148.     for (i = 0; i < G.vexnum; i++) {
  149.         if (!Visited[i]) {
  150.             EnQueue(&que, i);
  151.             Visited[i] = 1;
  152.             while (que.rear != que.front) {
  153.                 DeQueue(&que, &index);
  154.                 printf("%d ", G.vertices[index].data);
  155.                 temp = G.vertices[index].firstarc;
  156.                 while (temp) {
  157.                     if (!Visited[temp->adjvex]) {
  158.                         EnQueue(&que, temp->adjvex);
  159.                         Visited[temp->adjvex] = 1;
  160.                     }
  161.                     temp = temp->nextarc;
  162.                 }
  163.             }
  164.         }
  165.     }
  166.     printf("\n");
  167. }

  168. int main() {
  169.     Graph G;
  170.     CreateGraph(&G);
  171.     printf("广度优先遍历结果:\n");
  172.     BFSTraverse(G);
  173.     return 0;
  174. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-6-6 00:02:31 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-6-6 00:03:56 | 显示全部楼层

麻烦问一下,我的bfs函数问题出在哪里啊?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-7 19:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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