鱼C论坛

 找回密码
 立即注册
查看: 1666|回复: 11

[已解决]请帮我看一下关于无向图的建立代码,为怎么我的运行一半输入结果的时候运行不了了

[复制链接]
发表于 2021-12-16 12:39:41 | 显示全部楼层 |阅读模式

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

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

x
  1. //编译环境 vs2019
  2. //头文件:GraphModel.h
  3. #pragma once
  4. #define ok 1
  5. #define ERROR 0
  6. #define Max_VERTEX 100

  7. /** 图的类型枚举*/
  8. typedef enum {
  9.     UDG,//无向图
  10.     DG, //有向图
  11.     DN, //有向网
  12.     UDN//无向网
  13. }Graphkind;


  14. /**设置顶点的数据类型为字符型,记得分配内存*/
  15. typedef char* VerTexType;

  16. /**设置权值的整数类型*/
  17. typedef int ArcType;

  18. /**设置返回状态类型*/
  19. typedef int status;

  20. //头文件:MatrixGraph.h
  21. #ifndef MATRIXGRAPH_H_INCLUDED
  22. #define MATRIXGRAPH_H_INCLUDED
  23. #pragma once
  24. #include<stdio.h>
  25. #include<stdlib.h>
  26. #include "GraphModel.h"
  27. typedef struct {
  28.     VerTexType vertex[Max_VERTEX]; //顶点的数组存储类型
  29.     ArcType arc[Max_VERTEX][Max_VERTEX]; //邻接矩阵的数据存储类型
  30.     int vercountry;                           //顶点的个数
  31.     int arccountry;                    //图的边或弧的个数
  32.     Graphkind kind;                    //图的类型
  33. }MatrixGraph;
  34. #endif
  35. /**创建无向图*/
  36. status creativeGDU(MatrixGraph*G);
  37. status dispaly();
  38. int localver(MatrixGraph*G,VerTexType ver);

  39. //MatrixGraph.c文件
  40. #define _CRT_SECURE_NO_WARNINGS
  41. #include<malloc.h>
  42. #include<string.h>
  43. #include"MatrixGraph.h"
  44. /** 使用邻接矩阵表示法创建无向图*/
  45. //无向图特点:
  46. //1.无向图的邻接矩阵是对称的
  47. //2.顶点的度 = 第i行(列)中1的个数
  48. status creativeGDU(MatrixGraph*G) {
  49.     G-> kind = UDG;       //设置当前创建图的类型为无向图
  50.     printf("请输入顶点的个数:");
  51.     scanf("%d", &G->vercountry);

  52.     printf("请输入边的个数:");
  53.     scanf("%d", &G->arccountry);

  54.     printf("请依次输入顶点信息:\n");
  55.     for (int i = 0; i < G->vercountry; i++) {
  56.         G->vertex[i] = (VerTexType)malloc(sizeof(char) * 10);
  57.         printf("顶点%d:", i + 1);
  58.         scanf("%s", &G->vertex[i]);
  59.     }
  60.     //初始化邻接矩阵,所有边的权值设置为0
  61.     for (int i = 0; i < G->vercountry; i++) {
  62.         for (int j = 0; j < G->vercountry; j++) {
  63.             G->arc[i][j] = 0;
  64.         }
  65.     }
  66.     printf("请输入顶点和邻接顶点信息,构建邻接矩阵\n");
  67.     for (int i = 0; i < G->arccountry; i++) {
  68.         VerTexType ver1 = (VerTexType)malloc(sizeof(char) * 10);/*建立两个临时的内存存储每一次变化的,ver1和ver2
  69.                                                     这里出现错误了,之前我是把,ver1和ver2的内存分配放到for循环外面去了,这样是错误的,
  70.                                                     因为我在上面建立vertex[i]:每一个顶点数组元素分配内存时都是10个,这样会导致只装得了第一次的
  71.                                                     ver1和ver2第二次以上分配的会导致栈溢出。
  72.                                                     */
  73.         VerTexType ver2 = (VerTexType)malloc(sizeof(char) * 10);
  74.         printf("顶点:");
  75.         scanf("%s", ver1);
  76.         printf("\n");
  77.         printf("邻接点");
  78.         scanf("%s", ver2);
  79.         //分别获得两个顶点在顶点数组中的坐标
  80.         int x = localver(G, ver1);
  81.         int y = localver(G, ver2);
  82.         if (x == -1 || y == -1) {
  83.             return ERROR;
  84.         }
  85.         G->arc[x][y] = 1;
  86.         G->arc[y][x] = G->arc[x][y];
  87.         free(ver1); //这里要注意每一次遍历时都要释放这两个临时空间
  88.         free(ver2);
  89.     }
  90.    
  91. }
  92. /**返回某个顶点在顶点集合中的下标(从0开始),不存在返回-1*/
  93. int localver(MatrixGraph*G,VerTexType ver) {
  94.     int index = 0;
  95.     while (index < G->vercountry) {   //bug: 这里应该是顶点的数量我写成了边的数量                     
  96.         
  97.         if (strcmp(G->vertex[index], ver) == 0) {  /**
  98.                                                    这里也非常关键,ver是用户输入的顶点元素,用到的是
  99.                                                    strcmp()字符串比较函数 ,这里是两个字符串相等的意思
  100.                                                  */
  101.             break;
  102.         }
  103.         index++;
  104.     }
  105.    
  106.     return index == G->vercountry ? -1 : index;  /**
  107.                                                  这里非常重要,如果用户输入的不在存在顶点的范围内,等到下标
  108.                                                  加到最后一个顶点,就会返回-1,报错ERROR
  109.                                                  */
  110. }
  111. status display(MatrixGraph*G){
  112.     status status = creativeGDU(&G);
  113.     if (status == ERROR) {
  114.         printf("无向图创建失败");
  115.     }
  116.     printf("邻接矩阵创建无向图\n");
  117.     for (int i = 0; i < G->vercountry; i++) {
  118.         printf("\t%s", G->vertex[i]);
  119.     }
  120.     printf("\n");
  121.     for (int i = 0; i < G->vercountry; i++) {
  122.         printf("\t%s", G->vertex[i]);
  123.         for (int j = 0; j < G->vercountry; j++) {
  124.             printf("\t%s", G->arc[i][j]);
  125.         }
  126.         printf("\n");
  127.     }
  128.     return ok;
  129. }
  130. //main.c

  131. #include"MatrixGraph.h"
  132. #include<stdio.h>
  133. #include<stdlib.h>
  134. int main() {
  135.     MatrixGraph G;
  136.     display(&G);
  137.     return 0;
  138. }
复制代码
最佳答案
2021-12-16 14:43:24
哦,忘了还有这个
  1. main.c:105:1: warning: control reaches end of non-void function [-Wreturn-type]
  2.   105 | }
  3.       | ^
复制代码

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

使用道具 举报

 楼主| 发表于 2021-12-16 12:40:41 | 显示全部楼层
本帖最后由 莫启飞 于 2021-12-16 13:44 编辑

运行图片
[img](https://img-mid.csdnimg.cn/relea ... 770477926936181.png "#left")

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

使用道具 举报

 楼主| 发表于 2021-12-16 12:46:33 | 显示全部楼层
运行图片地址
[img]%5Bimg%5D(

                               
登录/注册后可看大图
"#left")[/img]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-16 13:52:55 | 显示全部楼层
莫启飞 发表于 2021-12-16 12:46
运行图片地址
"#left")[/img]

图片看不了,你以文本的形式发一下吧
你输入了什么?报了什么错?你期望输出什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-16 14:34:34 | 显示全部楼层
你的编译器没有任何警告?
  1. $ gcc-debug -o main main.c
  2. main.c: In function ‘creativeGDU’:
  3. main.c:70:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
  4.    70 |         scanf("%s", &G->vertex[i]);
  5.       |                ~^   ~~~~~~~~~~~~~
  6.       |                 |   |
  7.       |                 |   char **
  8.       |                 char *
  9. main.c: In function ‘display’:
  10. main.c:131:33: warning: passing argument 1 of ‘creativeGDU’ from incompatible pointer type [-Wincompatible-pointer-type ]
  11.   131 |     status status = creativeGDU(&G);
  12.       |                                 ^~
  13.       |                                 |
  14.       |                                 MatrixGraph **
  15. main.c:57:33: note: expected ‘MatrixGraph *’ but argument is of type ‘MatrixGraph **’
  16.    57 | status creativeGDU(MatrixGraph *G) {
  17.       |                    ~~~~~~~~~~~~~^
  18. main.c:143:24: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘ArcType’ {aka ‘int’} [-Wformat=]
  19.   143 |             printf("\t%s", G->arc[i][j]);
  20.       |                       ~^   ~~~~~~~~~~~~
  21.       |                        |            |
  22.       |                        char *       ArcType {aka int}
  23.       |                       %d
  24. main.c: In function ‘creativeGDU’:
  25. main.c:105:1: warning: control reaches end of non-void function [-Wreturn-type]
  26.   105 | }
  27.       | ^
  28. $
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-16 14:40:28 | 显示全部楼层
scanf("%s", &G->vertex[i]);
%s 要一个 char *,你给的是一个 char **

status status = creativeGDU(&G);
creativeGDU 要一个 MatrixGraph *,你给的是一个 MatrixGraph **

printf("\t%s", G->arc[i][j]);
%s 要一个 char *,你给的是一个 int

先不说你代码的逻辑问题了,这代码语法关就没过
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-16 14:43:24 | 显示全部楼层    本楼为最佳答案   
哦,忘了还有这个
  1. main.c:105:1: warning: control reaches end of non-void function [-Wreturn-type]
  2.   105 | }
  3.       | ^
复制代码

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

使用道具 举报

 楼主| 发表于 2021-12-16 19:09:43 | 显示全部楼层
人造人 发表于 2021-12-16 13:52
图片看不了,你以文本的形式发一下吧
你输入了什么?报了什么错?你期望输出什么?

你好,我想输入的是这样的
           请输入无向图的顶点数: 4
请输入边的数量: 4
依次输入顶点信息
顶点0: V1
顶点1: V2
顶点2: V3
顶点3:_ V4      
请输入顶点和邻接顶点信息,构建邻接矩阵
顶点: V1
邻接点: V2
顶点: V4
邻接点: V1
顶点: V3
邻接点: V1
顶点: V3
邻接点: V4,
打印图的邻接矩阵:
             v1       v2           v3           v4
v1         0          1            1             1
v2         1          0            0             0
v3         1          0            0             1
v4         1          0            1              0


到这里的时候报错了:if (strcmp(G->vertex[index], ver) == 0) {
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-16 19:35:40 | 显示全部楼层
人造人 发表于 2021-12-16 14:40
scanf("%s", &G->vertex);
%s 要一个 char *,你给的是一个 char **

for (int i = 0; i < G->vercountry; i++) {
        G->vertex = (VerTexType)malloc(sizeof(char) * 10);
        printf("顶点%d:", i + 1);
        scanf("%s", &G->vertex);  //我知道了,把&去掉就可以了,这样的话难道意思是说,G->vertex指向的是数组元素的首地址,是个指针吗(地址),就不用加&了吗
    }

printf("\t%s", G->arc[j]);  还有把%S 改成%d 就可以了


感谢大佬的解答



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

使用道具 举报

发表于 2021-12-16 20:02:18 | 显示全部楼层
莫启飞 发表于 2021-12-16 19:35
for (int i = 0; i < G->vercountry; i++) {
        G->vertex = (VerTexType)malloc(sizeof(char) *  ...

改好了

  1. //编译环境 vs2019
  2. //头文件:GraphModel.h
  3. //#pragma once

  4. //#define ok 1
  5. #define OK 1
  6. #define ERROR 0
  7. #define Max_VERTEX 100

  8. /** 图的类型枚举*/
  9. typedef enum {
  10.     UDG, //无向图
  11.     DG,  //有向图
  12.     DN,  //有向网
  13.     UDN  //无向网
  14. } Graphkind;

  15. /**设置顶点的数据类型为字符型,记得分配内存*/
  16. typedef char *VerTexType;

  17. /**设置权值的整数类型*/
  18. typedef int ArcType;

  19. /**设置返回状态类型*/
  20. typedef int status;

  21. //头文件:MatrixGraph.h
  22. #ifndef MATRIXGRAPH_H_INCLUDED
  23. #define MATRIXGRAPH_H_INCLUDED
  24. //#pragma once

  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. //#include "GraphModel.h"
  28. typedef struct {
  29.     VerTexType vertex[Max_VERTEX];       //顶点的数组存储类型
  30.     ArcType arc[Max_VERTEX][Max_VERTEX]; //邻接矩阵的数据存储类型
  31.     int vercountry;                      //顶点的个数
  32.     int arccountry;                      //图的边或弧的个数
  33.     Graphkind kind;                      //图的类型
  34. } MatrixGraph;
  35. #endif

  36. /**创建无向图*/
  37. status creativeGDU(MatrixGraph *G);
  38. status dispaly();
  39. int localver(MatrixGraph *G, VerTexType ver);

  40. // MatrixGraph.c文件
  41. //#define _CRT_SECURE_NO_WARNINGS
  42. #include <malloc.h>
  43. #include <string.h>
  44. //#include "MatrixGraph.h"
  45. /** 使用邻接矩阵表示法创建无向图*/
  46. //无向图特点:
  47. // 1.无向图的邻接矩阵是对称的
  48. // 2.顶点的度 = 第i行(列)中1的个数
  49. status creativeGDU(MatrixGraph *G) {
  50.     G->kind = UDG; //设置当前创建图的类型为无向图
  51.     printf("请输入顶点的个数:");
  52.     scanf("%d", &G->vercountry);

  53.     printf("请输入边的个数:");
  54.     scanf("%d", &G->arccountry);

  55.     printf("请依次输入顶点信息:\n");
  56.     for(int i = 0; i < G->vercountry; i++) {
  57.         //G->vertex[i] = (VerTexType)malloc(sizeof(char) * 10);
  58.         G->vertex[i] = malloc(sizeof(*G->vertex[i]) * 10);
  59.         //printf("顶点%d:", i + 1);
  60.         printf("顶点%d: ", i);
  61.         //scanf("%s", &G->vertex[i]);
  62.         scanf("%s", G->vertex[i]);
  63.     }
  64.     //初始化邻接矩阵,所有边的权值设置为0
  65.     for(int i = 0; i < G->vercountry; i++) {
  66.         for(int j = 0; j < G->vercountry; j++) {
  67.             G->arc[i][j] = 0;
  68.         }
  69.     }
  70.     printf("请输入顶点和邻接顶点信息,构建邻接矩阵\n");
  71.     for(int i = 0; i < G->arccountry; i++) {
  72.         //VerTexType ver1 = (VerTexType)malloc(sizeof(char) * 10);
  73.         VerTexType ver1 = malloc(sizeof(*ver1) * 10);
  74.     /*建立两个临时的内存存储每一次变化的,ver1和ver2
  75.      这里出现错误了,之前我是把,ver1和ver2的内存分配放到for循环外面去了,这样是错误的,
  76.      因为我在上面建立vertex[i]:每一个顶点数组元素分配内存时都是10个,这样会导致只装得了第一次的
  77.      ver1和ver2第二次以上分配的会导致栈溢出。
  78.      */
  79.         //VerTexType ver2 = (VerTexType)malloc(sizeof(char) * 10);
  80.         VerTexType ver2 = malloc(sizeof(*ver2) * 10);
  81.         printf("顶点:");
  82.         scanf("%s", ver1);
  83.         //printf("\n");
  84.         printf("邻接点");
  85.         scanf("%s", ver2);
  86.         //分别获得两个顶点在顶点数组中的坐标
  87.         int x = localver(G, ver1);
  88.         int y = localver(G, ver2);
  89.         if(x == -1 || y == -1) {

  90.             free(ver1);
  91.             free(ver2);

  92.             // 这里就直接返回?
  93.             // 直接返回会发生什么?
  94.             // 下面的那两个free函数调用就执行不到了吧?
  95.             return ERROR;
  96.         }
  97.         /*
  98.         G->arc[x][y] = 1;
  99.         G->arc[y][x] = G->arc[x][y];
  100.         */
  101.         G->arc[x][y] = 1;
  102.         G->arc[y][x] = 1;
  103.         free(ver1); //这里要注意每一次遍历时都要释放这两个临时空间
  104.         free(ver2);
  105.     }

  106.     return OK;
  107. }

  108. /**返回某个顶点在顶点集合中的下标(从0开始),不存在返回-1*/
  109. int localver(MatrixGraph *G, VerTexType ver) {
  110.     int index = 0;
  111.     while(index < G->vercountry) { // bug: 这里应该是顶点的数量我写成了边的数量

  112.         if(strcmp(G->vertex[index], ver) == 0) {
  113.                 /**
  114.                   这里也非常关键,ver是用户输入的顶点元素,用到的是
  115.                   strcmp()字符串比较函数 ,这里是两个字符串相等的意思
  116.                 */

  117.             return index;
  118.             //break;
  119.         }
  120.         index++;
  121.     }
  122.     return -1;
  123. #if 0
  124.     return index == G->vercountry
  125.                ? -1
  126.                : index; /**
  127.                         这里非常重要,如果用户输入的不在存在顶点的范围内,等到下标
  128.                         加到最后一个顶点,就会返回-1,报错ERROR
  129.                         */
  130. #endif
  131. }

  132. status display(MatrixGraph *G) {
  133.     //status status = creativeGDU(&G);
  134.     status status = creativeGDU(G);
  135.     if(status == ERROR) {
  136.         printf("无向图创建失败");
  137.     }
  138.     printf("邻接矩阵创建无向图\n");


  139.     printf("\t");

  140.     for(int i = 0; i < G->vercountry; i++) {
  141.         printf("\t%s", G->vertex[i]);
  142.     }
  143.     printf("\n");
  144.     for(int i = 0; i < G->vercountry; i++) {
  145.         printf("\t%s", G->vertex[i]);
  146.         for(int j = 0; j < G->vercountry; j++) {
  147.             //printf("\t%s", G->arc[i][j]);
  148.             printf("\t%d", G->arc[i][j]);
  149.         }
  150.         printf("\n");
  151.     }
  152.     //return ok;
  153.     return OK;
  154. }

  155. // 你是不是少写了一个函数?
  156. // 申请了内存不需要释放?
  157. void matrix_graph_free(MatrixGraph *g) {
  158.     for(size_t i = 0; i < g->vercountry; ++i) {
  159.         free(g->vertex[i]);
  160.     }
  161. }

  162. // main.c
  163. //#include "MatrixGraph.h"
  164. #include <stdio.h>
  165. #include <stdlib.h>

  166. int main() {
  167.     MatrixGraph G;
  168.     display(&G);
  169.     matrix_graph_free(&G);
  170.     return 0;
  171. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2021-12-16 20:03:18 | 显示全部楼层
  1. $ gcc-debug -o main main.c
  2. $ ./main
  3. 请输入顶点的个数:4
  4. 请输入边的个数:4
  5. 请依次输入顶点信息:
  6. 顶点0: V1
  7. 顶点1: V2
  8. 顶点2: V3
  9. 顶点3: V4
  10. 请输入顶点和邻接顶点信息,构建邻接矩阵
  11. 顶点:V1
  12. 邻接点V2
  13. 顶点:V4
  14. 邻接点V1
  15. 顶点:V3
  16. 邻接点V1
  17. 顶点:V3
  18. 邻接点V4
  19. 邻接矩阵创建无向图
  20.                 V1        V2        V3        V4
  21.         V1        0        1        1        1
  22.         V2        1        0        0        0
  23.         V3        1        0        0        1
  24.         V4        1        0        1        0
  25. $
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-16 20:15:52 | 显示全部楼层
谢谢你感谢大佬的解答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-6-2 17:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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