鱼C论坛

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

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

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

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

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

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

/** 图的类型枚举*/
typedef enum {
    UDG,//无向图
    DG, //有向图
    DN, //有向网
    UDN//无向网
}Graphkind;


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

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

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

//头文件:MatrixGraph.h
#ifndef MATRIXGRAPH_H_INCLUDED
#define MATRIXGRAPH_H_INCLUDED
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include "GraphModel.h"
typedef struct {
    VerTexType vertex[Max_VERTEX]; //顶点的数组存储类型
    ArcType arc[Max_VERTEX][Max_VERTEX]; //邻接矩阵的数据存储类型
    int vercountry;                           //顶点的个数
    int arccountry;                    //图的边或弧的个数
    Graphkind kind;                    //图的类型
}MatrixGraph;
#endif
/**创建无向图*/
status creativeGDU(MatrixGraph*G);
status dispaly();
int localver(MatrixGraph*G,VerTexType ver);

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

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

    printf("请依次输入顶点信息:\n");
    for (int i = 0; i < G->vercountry; i++) {
        G->vertex[i] = (VerTexType)malloc(sizeof(char) * 10);
        printf("顶点%d:", i + 1);
        scanf("%s", &G->vertex[i]);
    }
    //初始化邻接矩阵,所有边的权值设置为0
    for (int i = 0; i < G->vercountry; i++) {
        for (int j = 0; j < G->vercountry; j++) {
            G->arc[i][j] = 0;
        }
    }
    printf("请输入顶点和邻接顶点信息,构建邻接矩阵\n");
    for (int i = 0; i < G->arccountry; i++) {
        VerTexType ver1 = (VerTexType)malloc(sizeof(char) * 10);/*建立两个临时的内存存储每一次变化的,ver1和ver2
                                                    这里出现错误了,之前我是把,ver1和ver2的内存分配放到for循环外面去了,这样是错误的,
                                                    因为我在上面建立vertex[i]:每一个顶点数组元素分配内存时都是10个,这样会导致只装得了第一次的
                                                    ver1和ver2第二次以上分配的会导致栈溢出。
                                                    */
        VerTexType ver2 = (VerTexType)malloc(sizeof(char) * 10);
        printf("顶点:");
        scanf("%s", ver1);
        printf("\n");
        printf("邻接点");
        scanf("%s", ver2);
        //分别获得两个顶点在顶点数组中的坐标
        int x = localver(G, ver1);
        int y = localver(G, ver2);
        if (x == -1 || y == -1) {
            return ERROR;
        }
        G->arc[x][y] = 1;
        G->arc[y][x] = G->arc[x][y];
        free(ver1); //这里要注意每一次遍历时都要释放这两个临时空间
        free(ver2);
    }
    
}
/**返回某个顶点在顶点集合中的下标(从0开始),不存在返回-1*/
int localver(MatrixGraph*G,VerTexType ver) {
    int index = 0;
    while (index < G->vercountry) {   //bug: 这里应该是顶点的数量我写成了边的数量                     
        
        if (strcmp(G->vertex[index], ver) == 0) {  /**
                                                   这里也非常关键,ver是用户输入的顶点元素,用到的是
                                                   strcmp()字符串比较函数 ,这里是两个字符串相等的意思
                                                 */
            break;
        }
        index++;
    }
    
    return index == G->vercountry ? -1 : index;  /**
                                                 这里非常重要,如果用户输入的不在存在顶点的范围内,等到下标
                                                 加到最后一个顶点,就会返回-1,报错ERROR
                                                 */
}
status display(MatrixGraph*G){
    status status = creativeGDU(&G);
    if (status == ERROR) {
        printf("无向图创建失败");
    }
    printf("邻接矩阵创建无向图\n");
    for (int i = 0; i < G->vercountry; i++) {
        printf("\t%s", G->vertex[i]);
    }
    printf("\n");
    for (int i = 0; i < G->vercountry; i++) {
        printf("\t%s", G->vertex[i]);
        for (int j = 0; j < G->vercountry; j++) {
            printf("\t%s", G->arc[i][j]);
        }
        printf("\n");
    }
    return ok;
}
//main.c

#include"MatrixGraph.h"
#include<stdio.h>
#include<stdlib.h>
int main() {
    MatrixGraph G;
    display(&G);
    return 0;
}
最佳答案
2021-12-16 14:43:24
哦,忘了还有这个
main.c:105:1: warning: control reaches end of non-void function [-Wreturn-type]
  105 | }
      | ^
想知道小甲鱼最近在做啥?请访问 -> 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 | 显示全部楼层
你的编译器没有任何警告?
$ gcc-debug -o main main.c
main.c: In function ‘creativeGDU’:
main.c:70:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
   70 |         scanf("%s", &G->vertex[i]);
      |                ~^   ~~~~~~~~~~~~~
      |                 |   |
      |                 |   char **
      |                 char *
main.c: In function ‘display’:
main.c:131:33: warning: passing argument 1 of ‘creativeGDU’ from incompatible pointer type [-Wincompatible-pointer-type ]
  131 |     status status = creativeGDU(&G);
      |                                 ^~
      |                                 |
      |                                 MatrixGraph **
main.c:57:33: note: expected ‘MatrixGraph *’ but argument is of type ‘MatrixGraph **’
   57 | status creativeGDU(MatrixGraph *G) {
      |                    ~~~~~~~~~~~~~^
main.c:143:24: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘ArcType’ {aka ‘int’} [-Wformat=]
  143 |             printf("\t%s", G->arc[i][j]);
      |                       ~^   ~~~~~~~~~~~~
      |                        |            |
      |                        char *       ArcType {aka int}
      |                       %d
main.c: In function ‘creativeGDU’:
main.c:105:1: warning: control reaches end of non-void function [-Wreturn-type]
  105 | }
      | ^
$
想知道小甲鱼最近在做啥?请访问 -> 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 | 显示全部楼层    本楼为最佳答案   
哦,忘了还有这个
main.c:105:1: warning: control reaches end of non-void function [-Wreturn-type]
  105 | }
      | ^
想知道小甲鱼最近在做啥?请访问 -> 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[i] = (VerTexType)malloc(sizeof(char) * 10);
        printf("顶点%d:", i + 1);
        scanf("%s", &G->vertex[i]);  //我知道了,把&去掉就可以了,这样的话难道意思是说,G->vertex[i]指向的是数组元素的首地址,是个指针吗(地址),就不用加&了吗
    }

printf("\t%s", G->arc[i][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) *  ...

改好了
//编译环境 vs2019
//头文件:GraphModel.h
//#pragma once

//#define ok 1
#define OK 1
#define ERROR 0
#define Max_VERTEX 100

/** 图的类型枚举*/
typedef enum {
    UDG, //无向图
    DG,  //有向图
    DN,  //有向网
    UDN  //无向网
} Graphkind;

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

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

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

//头文件:MatrixGraph.h
#ifndef MATRIXGRAPH_H_INCLUDED
#define MATRIXGRAPH_H_INCLUDED
//#pragma once

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

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

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

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

    printf("请依次输入顶点信息:\n");
    for(int i = 0; i < G->vercountry; i++) {
        //G->vertex[i] = (VerTexType)malloc(sizeof(char) * 10);
        G->vertex[i] = malloc(sizeof(*G->vertex[i]) * 10);
        //printf("顶点%d:", i + 1);
        printf("顶点%d: ", i);
        //scanf("%s", &G->vertex[i]);
        scanf("%s", G->vertex[i]);
    }
    //初始化邻接矩阵,所有边的权值设置为0
    for(int i = 0; i < G->vercountry; i++) {
        for(int j = 0; j < G->vercountry; j++) {
            G->arc[i][j] = 0;
        }
    }
    printf("请输入顶点和邻接顶点信息,构建邻接矩阵\n");
    for(int i = 0; i < G->arccountry; i++) {
        //VerTexType ver1 = (VerTexType)malloc(sizeof(char) * 10);
        VerTexType ver1 = malloc(sizeof(*ver1) * 10);
    /*建立两个临时的内存存储每一次变化的,ver1和ver2
     这里出现错误了,之前我是把,ver1和ver2的内存分配放到for循环外面去了,这样是错误的,
     因为我在上面建立vertex[i]:每一个顶点数组元素分配内存时都是10个,这样会导致只装得了第一次的
     ver1和ver2第二次以上分配的会导致栈溢出。
     */
        //VerTexType ver2 = (VerTexType)malloc(sizeof(char) * 10);
        VerTexType ver2 = malloc(sizeof(*ver2) * 10);
        printf("顶点:");
        scanf("%s", ver1);
        //printf("\n");
        printf("邻接点");
        scanf("%s", ver2);
        //分别获得两个顶点在顶点数组中的坐标
        int x = localver(G, ver1);
        int y = localver(G, ver2);
        if(x == -1 || y == -1) {

            free(ver1);
            free(ver2);

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

    return OK;
}

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

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

            return index;
            //break;
        }
        index++;
    }
    return -1;
#if 0
    return index == G->vercountry
               ? -1
               : index; /**
                        这里非常重要,如果用户输入的不在存在顶点的范围内,等到下标
                        加到最后一个顶点,就会返回-1,报错ERROR
                        */
#endif
}

status display(MatrixGraph *G) {
    //status status = creativeGDU(&G);
    status status = creativeGDU(G);
    if(status == ERROR) {
        printf("无向图创建失败");
    }
    printf("邻接矩阵创建无向图\n");


    printf("\t");

    for(int i = 0; i < G->vercountry; i++) {
        printf("\t%s", G->vertex[i]);
    }
    printf("\n");
    for(int i = 0; i < G->vercountry; i++) {
        printf("\t%s", G->vertex[i]);
        for(int j = 0; j < G->vercountry; j++) {
            //printf("\t%s", G->arc[i][j]);
            printf("\t%d", G->arc[i][j]);
        }
        printf("\n");
    }
    //return ok;
    return OK;
}

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

// main.c
//#include "MatrixGraph.h"
#include <stdio.h>
#include <stdlib.h>

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

使用道具 举报

发表于 2021-12-16 20:03:18 | 显示全部楼层
$ gcc-debug -o main main.c
$ ./main
请输入顶点的个数: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
$ 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 16:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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