So i have this file format like this
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
where column one
represents vertex1
, column 2
represents weight
, and column 3
represents vertex2
the vertex to which vertex 1 is connected to.
I have to do more but for now i just have to print this and we have to use linked lists to do it.
This is my take on the exercise
#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;
}
The functions you can guess their meaning by the names so i doubt i need to explain much but if you question the not used variables in the structures its because its for the 2nd part of the exercise which i will solve after i print this.
Thing is when i print the exercise it shows this
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
Which is mostly correct but the first row. The first row should not be there. Any idea on how to fix it?
If you search for tTt
in your input you will see that tTt
has only ingoing vertex, hence your output looks good from the perspective of tTt
. Of course, you might decide not to output items only having outgoing vertex, so in your
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;
}
instead of printf
‘ing your node, you can do the printf
only when you realized there is something to point to. But this seems to be optional and your code seems to be good as it is.
In graph_write
, check to see if edge
is NULL
before printing the vertex name and ->
. If the vertex doesn’t lead anywhere, there’s no need to print anything.
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;
}
}
wow.. AMAZING. Apparently tTt is simply not connected to anything. Its not a print error. The code is correct as it is
If you change the line
while (fscanf(fp, "%s %d %s", name1, &weight, name2) != EOF) {
towhile (fscanf(fp, "%s %d %s", name1, &weight, name2) == 3) {
, does the bug disappear?@AndreasWenzel Its not a bug. The code is correct. i asked chat gdp to come up with a txt file cuz i was too lazy to write it myself (i have picture slides so i cant copy paste) and didnt realize that the last node simply wasnt connected to anything