鱼C论坛

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

求助

[复制链接]
发表于 2024-6-7 22:16:26 | 显示全部楼层 |阅读模式

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

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

x
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define MAXV 50
  4. #define INF 32767     //表示∞

  5. typedef char VertexType;         //顶点的数据类型
  6. typedef int EdgeType;            //带权图中边上权值的数据类型

  7. typedef struct {
  8.         VertexType Vex[MAXV];           //顶点表
  9.         EdgeType edges[MAXV][MAXV];     //邻接矩阵,边表
  10.         int n, e;                       //图的当前顶点数和边数
  11. }MGraph;                            //基于邻接矩阵法的带权无向图

  12. typedef struct
  13. {
  14.         int u;    //边的起始顶点
  15.         int v;    //边的终止顶点
  16.         int w;    //边的权值
  17. }Edge;

  18. void CreateMGraph(MGraph *G)
  19. {
  20.         int i,j,k,w;
  21.         printf("请输入顶点数和边数,用空格隔开:\n");
  22.         scanf("%d %d",&G->n,&G->e);
  23.         fflush(stdin);
  24.        
  25.         printf("请依次输入顶点的值:\n");
  26.         for(int i = 0;i < G->n; i++)
  27.         {
  28.                 printf("输入第%d个顶点信息:\n",i+1);
  29.                 scanf("%c",&G->Vex[i]);
  30.                 fflush(stdin);
  31.         }
  32.        
  33.         for(i = 0;i < G->n; i++)
  34.                 for(j = 0;j <G->n; j++)
  35.                         G->edges[i][j] = INF;
  36.                                
  37.         printf("输入边<vi,vj>的下标i,下标j和权w:\n");
  38.         for (k = 0; k < G->e; k++)                                               
  39.         {
  40.                 scanf("%d %d %d", &i, &j, &w);        //输入边<vi,vj>上的权值w
  41.                 G->edges[i][j] = w;
  42.                 G->edges[j][i] = G->edges[i][j];        //无向图矩阵是对称的
  43.         }
  44.        
  45. }

  46. void CreateMGraph2(MGraph *G)
  47. {
  48.         int i,j,k,w;
  49.         printf("请输入顶点数和边数,用空格隔开:\n");
  50.         scanf("%d %d",&G->n,&G->e);
  51.         fflush(stdin);
  52.        
  53.         printf("请依次输入顶点的值:\n");
  54.         for(int i = 0;i < G->n; i++)
  55.         {
  56.                 printf("输入第%d个顶点信息:\n",i+1);
  57.                 scanf("%c",&G->Vex[i]);
  58.                 fflush(stdin);
  59.         }
  60.        
  61.         for(i = 0;i < G->n; i++)
  62.                 for(j = 0;j <G->n; j++)
  63.                         G->edges[i][j] = INF;
  64.                                
  65.         printf("输入边<vi,vj>的下标i,下标j和权w:\n");
  66.         for (k = 0; k < G->e; k++)                                               
  67.         {
  68.                 scanf("%d%d%d", &i, &j, &w);
  69.                 G->edges[i][j] = w;
  70.         }
  71.        
  72. }

  73. void PrintMatrix(MGraph G)                                                       
  74. {
  75.         int i,j;
  76.         printf("邻接矩阵表示如下:\n");
  77.         for (i = 0; i < G.n; i++)
  78.         {
  79.                 for (j = 0; j < G.n; j++)
  80.                         printf("%-10d", G.edges[i][j]);
  81.                 printf("\n");
  82.         }
  83. }

  84. void PrintVex(MGraph g)
  85. {
  86.         printf("\n顶点集合为:");
  87.         for(int i=0;i<g.n;i++)
  88.                 printf("%c ",g.Vex[i]);
  89.         printf("\n");
  90. }

  91. void Prim(MGraph g,int v)
  92. {
  93.         int lowcost[MAXV];
  94.         int min;
  95.         int closest[MAXV],i,j,k;
  96.         printf("普里姆算法:\n");
  97.         for(i=0;i<g.n;i++)
  98.         {
  99.                 lowcost[i]=g.edges[v][i];
  100.                 closest[i]=v;
  101.         }
  102.         lowcost[v]=0;
  103.         for(i=1;i<g.n;i++)
  104.         {
  105.                 min=INF;
  106.                 for(j=0;j<g.n;j++)
  107.                         if(lowcost[j]!=0&&lowcost[j]<min)
  108.                         {
  109.                                 min=lowcost[j];
  110.                                 k=j;
  111.                         }
  112.                 printf("边(%d,%d)权为:%d\n",closest[k],k,min);
  113.                 lowcost[k]=0;
  114.                 for(j=0;j<g.n;j++)
  115.                         if(g.edges[k][j]<lowcost[j])
  116.                         {
  117.                                 lowcost[j]=g.edges[k][j];
  118.                                 closest[j]=k;
  119.                         }
  120.         }
  121. }

  122. void InsertSort(Edge r[],int n)
  123. {
  124.         int i,j;
  125.         for(i=2;i<n;i++)
  126.         {
  127.                 if(r[i].w<r[i-1].w)
  128.                 {
  129.                         r[0]=r[i];
  130.                         j=i-1;
  131.                         while(r[0].w<r[j].w&&j>=1)
  132.                         {
  133.                                 r[j+1]=r[j];
  134.                                 j=j-1;
  135.                         }
  136.                         r[j+1]=r[0];       
  137.                 }
  138.         }
  139. }

  140. void Kruskal(MGraph g)
  141. {
  142.         int i,j,u1,v1,sn1,sn2,k;
  143.         int vset[MAXV];
  144.         Edge E[MAXV];
  145.         k=0;
  146.         printf("克鲁斯卡尔算法:\n");
  147.         for(i=0;i<g.n;i++)
  148.                 for(j=0;j<g.n;j++)
  149.                         if(g.edges[i][j]!=0&&g.edges[i][j]!=INF)
  150.                         {
  151.                                 E[k].u=i;
  152.                                 E[k].v=j;
  153.                                 E[k].w=g.edges[i][j];
  154.                                 k++;
  155.                         }
  156.         InsertSort(E,g.e);
  157.         for(i=0;i<g.n;i++)
  158.                 vset[i]=i;
  159.         k=1;
  160.         j=0;
  161.         while(k<g.n)
  162.         {
  163.                 u1=E[j].u;
  164.                 v1=E[j].v;
  165.                 sn1=vset[u1];
  166.                 sn2=vset[v1];
  167.                 if(sn1!=sn2)
  168.                 {
  169.                         printf("边(%d,%d)权为:%d\n",u1,v1,E[j].w);
  170.                         k++;
  171.                         for(i=0;i<g.n;i++)
  172.                                 if(vset[i]==sn2)
  173.                                         vset[i]=sn1;
  174.                 }
  175.                 j++;
  176.         }
  177. }

  178. int main()
  179. {
  180.         MGraph G1;
  181.         CreateMGraph(&G1);
  182.         PrintVex(G1);
  183.         PrintMatrix(G1);
  184.         Prim(G1,0);
  185.         Kruskal(G1);
  186.         MGraph G2;
  187.         CreateMGraph2(&G2);
  188.         PrintVex(G2);
  189.         PrintMatrix(G2);
  190.         Prim(G2,0);
  191.         Kruskal(G2);
  192. }
复制代码

修改void Kruskal(MGraph g)函数或者void InsertSort(Edge r[],int n)函数使得能输出正确的最小生成树
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-6-7 22:17:05 | 显示全部楼层
这段代码是用来创建带权无向图的邻接矩阵表示的。不过有一些问题需要修正。

首先,在函数CreateMGraph和CreateMGraph2中,你使用了两个for循环变量i,这会导致第二个循环无法正常运行。建议将第二个循环变量改为j。

其次,在函数CreateMGraph和CreateMGraph2中,你在接收顶点的值时使用了scanf函数来接收一个字符,但是由于输入的时候还会有一个回车符,而scanf函数读取字符时会将回车符也读取进去,因此无法正常读取输入。建议使用getchar()函数来消耗掉回车符。

第三,在函数CreateMGraph和CreateMGraph2中,你在循环中为边矩阵每个元素都赋值为INF,但是你没有使用正确的下标来赋值。应该是G->edges[i][j] = INF;

最后,在函数CreateMGraph和CreateMGraph2中,你在循环中为边矩阵赋值时,只赋值了一次,而对于无向图来说,矩阵是对称的,即edges[j][i]也应该赋值为相同的权值。应该是G->edges[i][j] = G->edges[j][i] = w;

下面是修正过的代码:

  1. #include <stdio.h>
  2. #define MAXV 50
  3. #define INF 32767     //表示∞

  4. typedef char VertexType;         //顶点的数据类型
  5. typedef int EdgeType;            //带权图中边上权值的数据类型

  6. typedef struct {
  7.     VertexType Vex[MAXV];           //顶点表
  8.     EdgeType edges[MAXV][MAXV];     //邻接矩阵,边表
  9.     int n, e;                       //图的当前顶点数和边数
  10. }MGraph;                            //基于邻接矩阵法的带权无向图

  11. void CreateMGraph(MGraph *G)
  12. {
  13.     int i,j,k,w;
  14.     printf("请输入顶点数和边数,用空格隔开:\n");
  15.     scanf("%d %d",&G->n,&G->e);
  16.     getchar();
  17.    
  18.     printf("请依次输入顶点的值:\n");
  19.     for(int i = 0;i < G->n; i++)
  20.     {
  21.         printf("输入第%d个顶点信息:\n",i+1);
  22.         scanf("%c",&G->Vex[i]);
  23.         getchar();
  24.     }
  25.    
  26.     for(i = 0;i < G->n; i++)
  27.         for(j = 0;j < G->n; j++)
  28.             G->edges[i][j] = INF;
  29.                
  30.     printf("输入边的下标i,下标j和权w:\n");
  31.     for (k = 0; k < G->e; k++)                        
  32.     {
  33.         scanf("%d %d %d", &i, &j, &w);    //输入边上的权值w
  34.         G->edges[i][j] = G->edges[j][i] = w;    //无向图矩阵是对称的
  35.     }
  36.    
  37. }

  38. void CreateMGraph2(MGraph *G)
  39. {
  40.     int i,j,k,w;
  41.     printf("请输入顶点数和边数,用空格隔开:\n");
  42.     scanf("%d %d",&G->n,&G->e);
  43.     getchar();
  44.    
  45.     printf("请依次输入顶点的值:\n");
  46.     for(int i = 0;i < G->n; i++)
  47.     {
  48.         printf("输入第%d个顶点信息:\n",i+1);
  49.         scanf("%c",&G->Vex[i]);
  50.         getchar();
  51.     }
  52.    
  53.     for(i = 0;i < G->n; i++)
  54.         for(j = 0;j < G->n; j++)
  55.             G->edges[i][j] = INF;
  56.                
  57.     printf("输入边的下标i,下标j和权w:\n");
  58.     for (k = 0; k < G->e; k++)                        
  59.     {
  60.         scanf("%d%d%d", &i, &j, &w);
  61.         G->edges[i][j] = G->edges[j][i] = w;
  62.     }
  63.    
  64. }

  65. void PrintMatrix(MGraph G)                          
  66. {
  67.     int i,j;
  68.     printf("邻接矩阵表示如下:\n");
  69.     for (i = 0; i < G.n; i++)
  70.     {
  71.         for (j = 0; j < G.n; j++)
  72.             printf("%-10d", G.edges[i][j]);
  73.         printf("\n");
  74.     }
  75. }

  76. int main()
  77. {
  78.     MGraph G;
  79.     CreateMGraph(&G);
  80.     PrintMatrix(G);
  81.     return 0;
  82. }
复制代码


现在你可以运行这段代码来创建一个带权无向图,并打印出邻接矩阵表示的图。祝你编程愉快!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-22 03:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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