【问题标题】:Converting an Adjacency Matrix to an Adjacency List in C在 C 中将邻接矩阵转换为邻接列表
【发布时间】:2021-11-04 04:53:17
【问题描述】:

我应该将给定的邻接矩阵转换为 C 中的邻接列表。我需要这个邻接列表,因为这是我将实现深度优先搜索 (DFS) 算法的地方。在我为 DFS 编写代码之前,我想确保我制作了正确的邻接列表。但是,我的问题是当我尝试运行我的代码时,程序没有继续打印图表。我相信这是因为我阅读用户输入的方式,因为这正是程序停止的地方。现在我的问题是,如何在一行中读取多个输入?我尝试使用 fgets() 但我的程序没有继续打印图形/邻接列表。下面提供的是我写的代码。

这里是结构节点:

typedef struct vertexnode VertexNode;
struct vertexnode
{
    int vertex;
    VertexNode *Next;
};

typedef struct graph 
{
    int numVertices;
    VertexNode **adjLists;
} Graph;

下面是主要功能:

int main()
{
    int size, i, temp;
    //char input1[100000];

    scanf("%d\n", &size);   // scan number of vertices
    Graph *graph = createAGraph(size);

    for(i = 0; i < size; i++)  // scan the adjacency MATRIX
    {
        char input1[100000];
        int j = 0;
        fgets(input1, sizeof(input1), stdin);
        char *piece = strtok(input1, " "); // extract first number
        while(piece != NULL)
        {
            temp = atoi(piece); // convert from char to int
            if(temp == 1)   // create new node
            {
                addEdge(graph, i, j); //add edge from vertex i to j
            }
            j++;
            piece = strtok(NULL, " ");
        }
    }

    printGraph(graph);
    return 0;
}

创建顶点的函数:

VertexNode *createVertex(int vertexNum)
{
    VertexNode *new_vertex = (VertexNode *) malloc(sizeof(VertexNode));
    new_vertex->vertex = vertexNum + 1;
    new_vertex->Next = NULL;
    return new_vertex;
}

创建图表的函数:

Graph *createAGraph(int size)
{
    Graph *graph = (Graph *)malloc(sizeof(Graph));
    graph->numVertices = size;
    graph->adjLists = (VertexNode **)malloc(sizeof(VertexNode *));

    for(int i = 0; i < size; i++)
        graph->adjLists[i] = NULL;
    return graph;
}

addEdge 的函数:

void addEdge(Graph *graph, int s, int d)
{
    VertexNode *newNode = createVertex(d);
    newNode->Next = graph->adjLists[s];
    graph->adjLists[s] = newNode;
}

打印邻接表的函数:

void printGraph(Graph *graph)
{
    for(int i = 0; i < graph->numVertices; i++)
    {
        VertexNode *temp = graph->adjLists[i];
        printf("\n Vertex %d\n: ", i+1);
        while(temp)
        {
            printf("%d -> ", temp->vertex);
            temp = temp->Next;
        }
        newline;
    }
}

考虑到我们必须在一行中读取多个输入并且有任意数量的行,是否有更好的方法来获取用户输入?

示例输入:

4   
0 0 1 0  
1 0 0 1  
1 1 0 1  
0 1 0 0 

第一个输入是列表中的顶点数
后面的行代表邻接矩阵

邻接表应该是这样的:

1 -> 3  
2 -> 1 -> 4  
3 -> 1 -> 2 -> 4  
4 -> 2    

【问题讨论】:

  • “我的程序遇到了一些错误”。那些错误会是什么?请用确切的错误或不正确的行为更新问题。
  • 另外,代码不完整。要求调试帮助的问题必须提供完整的代码minimal reproducible example
  • 注意循环从 0 开始,而不是 1 :图形的边缘也是如此。
  • @kaylum 你好。我已经编辑了我的帖子。 :)
  • @JoëlHecht 是的。在函数VertexNode *createVertex(int vertexNum)下,我给顶点加1。

标签: c data-structures graph adjacency-matrix adjacency-list


【解决方案1】:

请您尝试以下方法:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main()
{
    int i, j, size;
    char *tk;                           // pointer to a token
    char delim[] = " ";                 // delimiter of tokens
    char line[BUFSIZ];
    int *m;                             // matrix

    fgets(line, BUFSIZ, stdin);         // read stdin and assign line
    size = atoi(line);                  // size of matrix

    if (NULL == (m = malloc(sizeof(int) * size * size))) {
                                        // allocate a matrix
        fprintf(stderr, "malloc failed\n");
        exit(1);
    }
    for (i = 0; i < size; i++) {
        if (NULL == fgets(line, BUFSIZ, stdin)) {
            fprintf(stderr, "insufficient lines\n");
            exit(1);
        }
        j = 0;
        tk = strtok(line, delim);
        while (tk != NULL) {
            m[i * size + j] = atoi(tk); // assign element of matrix
            j++;
            if (j > size) {
                fprintf(stderr, "too many columns\n");
                exit(1);
            }
            tk = strtok(NULL, delim);
        }
        if (j < size) {
            fprintf(stderr, "insufficient columns\n");
            exit(1);
        }
    }

    // print the adjacency list
    for (i = 0; i < size; i++) {
        printf("%d", i + 1);
        for (j = 0; j < size; j++) {
            if (m[i * size + j]) {
                printf(" -> %d", j + 1);
            }
        }
        printf("\n");
    }

    return 0;
}

由于我不知道您的特殊功能,例如 createAGraph()addEdge(),我使用了我自己的矩阵定义。请修改 我的代码来满足你的接口。

【讨论】:

  • 你好。谢谢你。但是,我确实需要使用链表制作一个邻接表(不仅仅是打印它)。因为我需要它来运行深度优先搜索 (DFS)。我已经更新了我的帖子,以防你想帮助我。 :)
  • 感谢您的反馈。很抱歉对列表有误解,但是如果您熟悉的话,将我的代码修改到链接列表中会很容易。如果您仍然有问题,请让我知道具体问题。我已准备好使用您的函数编写自己的代码,但我不确定它是否会帮助您研究数据结构。祝你好运和最好的问候。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-19
相关资源
最近更新 更多