You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正C语言链表实现的图打印多余行问题

问题修复:图打印时出现多余的tTt->行

问题背景

用链表实现图结构,读取的文件格式为:第一列是vertex1,第二列是weight,第三列是vertex1连接的vertex2。编写的C代码能正常读取文件并打印图,但输出时出现多余的tTt->行,其余输出正常。

文件内容

aAa     5     bBb
bBb     3     cCc
cCc     7     dDd
dDd     2     eEe
eEe     8     fFf
fFf     4     gGg
gGg     6     hHh
hHh     1     iIi
iIi     9     jJj
jJj     5     kKk
kKk     3     lLl
lLl     7     mMm
mMm     4     nNn
nNn     6     oOo
oOo     2     pPp
pPp     8     qQq
qQq     1     rRr
rRr     9     sSs
sSs     5     tTt

实现代码

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

typedef struct edge_s edge_t;
typedef struct vertex_s vertex_t;

struct edge_s {
    struct edge_s *next;
    int weight;
    vertex_t *vertex;
};

struct vertex_s {
    struct vertex_s *next;
    char *name;
    edge_t *edge;
    int traversed;
};

typedef struct graph_s {
    vertex_t *head;
    int n;
} graph_t;

vertex_t *find_vertex(graph_t *graph, const char name[20]);
void vertex_add(graph_t *graph, const char *name);
void edge_add(graph_t *graph, vertex_t *vertex1, vertex_t *vertex2, int weight);
graph_t *graph_init(void);
graph_t *fileread(const char *name);
void graph_write(graph_t *graph);

graph_t *graph_init() {
    graph_t *graph = malloc(sizeof(graph_t));
    if (graph == NULL)
        exit(EXIT_FAILURE);
    graph->head = NULL;
    graph->n = 0;

    return graph;
}

void edge_add(graph_t *graph, vertex_t *vertex1, vertex_t *vertex2, int weight) {
    edge_t *edge = malloc(sizeof(edge_t));
    if (edge == NULL)
        exit(EXIT_FAILURE);
    edge->weight = weight;
    edge->vertex = vertex2;
    edge->next = vertex1->edge;
    vertex1->edge = edge;
}

void vertex_add(graph_t *graph, const char *name) {
    vertex_t *vertex = malloc(sizeof(vertex_t));
    if (vertex == NULL)
        exit(EXIT_FAILURE);
    vertex->edge = NULL;
    vertex->traversed = 0;
    vertex->name = strdup(name);
    vertex->next = graph->head;
    graph->head = vertex;
}

vertex_t *find_vertex(graph_t *graph, const char name[20]) {
    vertex_t *v = graph->head;
    while (v != NULL) {
        if (strcmp(v->name, name) == 0)
            return v;
        v = v->next;
    }
    return NULL;
}

graph_t *fileread(const char *name) {
    FILE *fp = fopen(name, "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

    graph_t *graph = graph_init();
    int weight;
    char name1[20], name2[20];
    vertex_t *vertex1, *vertex2;

    while (fscanf(fp, "%s %d %s", name1, &weight, name2) != EOF) {
        vertex1 = find_vertex(graph, name1);
        if (vertex1 == NULL) {
            vertex_add(graph, name1);
            vertex1 = graph->head; 
        }

        vertex2 = find_vertex(graph, name2);
        if (vertex2 == NULL) {
            vertex_add(graph, name2);
            vertex2 = graph->head; 
        }

        edge_add(graph, vertex1, vertex2, weight);
    }


    fclose(fp);
    return graph;
}

void graph_write(graph_t *graph) {
    vertex_t *vertex = graph->head;
    edge_t *edge;

    while (vertex != NULL) {
        printf("%s->", vertex->name);
        edge = vertex->edge;
        while (edge != NULL) {
            printf(" %d -> %s", edge->weight, edge->vertex->name);
            edge = edge->next;
        }
        printf("\n");
        vertex = vertex->next;
    }
}

int main() {
    graph_t *graph = fileread("file");
    graph_write(graph);
    return 0;
}

当前输出

tTt->
sSs-> 5 -> tTt
rRr-> 9 -> sSs
qQq-> 1 -> rRr
pPp-> 8 -> qQq
oOo-> 2 -> pPp
nNn-> 6 -> oOo
mMm-> 4 -> nNn
lLl-> 7 -> mMm
kKk-> 3 -> lLl
jJj-> 5 -> kKk
iIi-> 9 -> jJj
hHh-> 1 -> iIi
gGg-> 6 -> hHh
fFf-> 4 -> gGg
eEe-> 8 -> fFf
dDd-> 2 -> eEe
cCc-> 7 -> dDd
bBb-> 3 -> cCc
aAa-> 5 -> bBb

问题原因

tTt是文件最后一行的vertex2,它被正常添加到图中,但没有任何出边(文件中没有以tTt作为vertex1的行)。当前的graph_write函数会无条件先打印顶点->,再遍历输出边信息,没有边时就直接换行,导致出现了多余的tTt->行。

修复方案

根据需求,有两种常见的修复方式:

方式一:只打印有出边的顶点

修改graph_write函数,在打印前判断顶点是否有出边,只有存在出边时才打印该行:

void graph_write(graph_t *graph) {
    vertex_t *vertex = graph->head;
    edge_t *edge;

    while (vertex != NULL) {
        edge = vertex->edge;
        // 仅当顶点有出边时才打印
        if (edge != NULL) {
            printf("%s->", vertex->name);
            while (edge != NULL) {
                printf(" %d -> %s", edge->weight, edge->vertex->name);
                edge = edge->next;
            }
            printf("\n");
        }
        vertex = vertex->next;
    }
}

方式二:打印所有顶点,但无出边时不显示箭头

如果需要保留所有顶点的输出,只是去掉无出边顶点的箭头,修改打印逻辑:

void graph_write(graph_t *graph) {
    vertex_t *vertex = graph->head;
    edge_t *edge;

    while (vertex != NULL) {
        edge = vertex->edge;
        if (edge != NULL) {
            printf("%s->", vertex->name);
            while (edge != NULL) {
                printf(" %d -> %s", edge->weight, edge->vertex->name);
                edge = edge->next;
            }
        } else {
            // 无出边时仅打印顶点名称
            printf("%s", vertex->name);
        }
        printf("\n");
        vertex = vertex->next;
    }
}

修复后效果

使用方式一修复后,输出中将不再出现tTt->行;使用方式二修复后,该行会变成tTt,不再显示多余的箭头。


内容的提问来源于stack exchange,提问作者Severjan Lici

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:34:56