[英]C Input for Directed Graphs
我们被告知输入文件将是一个简单的数字列表:
1 3 4
2 3
3 4
4 1 2
其中第一个数字是源节点,而后续的数字是它的相邻节点。
我试图弄清楚如何最好地存储它。 我想首先初始化一个“图形”,一个包含所有这些节点的数组。 然后,逐行读取文件后,我会将根节点存储到图数组中,然后使用以下数字更新该节点的列表(相邻节点),直到到达行尾为止,对每行重复此操作,直到EOF。
但是我在如何初始化图形上苦苦挣扎,我是否只是假设一定的大小并在达到大小后立即重新分配()? 我是否首先读取文件并计算行数以找出大小,然后重新读取文件以存储节点? 还有其他办法吗?
这是我的数据结构的代码:
int initialize (Graph *mygraph, int MaxSize) {
mygraph->MaxSize = MaxSize;
mygraph->table = (Node *)malloc(sizeof(Node) * MaxSize);
return 0;
}
int insert_node (Graph *mygraph, int n, char *name) {
mygraph->table[n].name = strdup(name);
mygraph->table[n].outdegree = 0;
return 0;
}
int insert_link (Graph *mygraph, int source, int target) {
List *newList = (List *)malloc(sizeof(List));
newList->index = target;
newList->next = mygraph->table[source].outlist;
mygraph->table[source].outlist = newList;
return 0;
}
因此,在读取文件后,
我初始化图。
我读取了第一个数字,并将其存储为新的图形节点。
我阅读下一个数字,直到打到\\ n,然后将它们存储为指向上述根节点的图形链接。
我会针对每一行执行此操作,直到达到EOF。
如您所见,在读取整个文件之前,我不知道“ MaxSize”是什么。
谢谢! 我对C相当陌生,所以如果做任何愚蠢的事,我都感到抱歉。
你可以有一些初步猜测MaxSize
(例如,8),需要你的数据(可能是当成长graph->MaxSize += graph->MaxSize/2
)使用realloc
,或只是malloc
-ing一个更大的新块,复制里面的旧块,然后free
该旧块)。 不要忘记检查任何malloc
或calloc
或realloc
调用的成功结果,它们可能(很少)失败。
注意,我不知道如何声明您的Graph
和Node
类型(只是猜测)。
我假设并猜测您已经声明了类似
typedef struct node_st Node;
typedef struct graph_st Graph;
struct node_st {
char*name; // strdup-ed
unsigned outdegree;
};
struct graph_st {
unsigned MaxSize;
Node* table; //calloc-ed, of allocated size MaxSize
};
因此,例如您的insert_node
函数可能是
void insert_node (Graph *mygraph, int n, char *name) {
assert (mygraph != NULL);
assert (n >= 0);
assert (name != NULL && *name != (char)0);
unsigned maxsize = mygraph->MaxSize;
if (maxsize <= n) {
unsigned newmaxsize = n + maxsize/2 + 1;
Node* newtable = calloc (newmaxsize, sizeof(Node));
if (!newtable)
perror("growing table in graph"), exit(EXIT_FAILURE);
for (unsigned i=0; i<maxsize; i++)
newtable[i] = mygraph->table[i];
free (mygraph->table);
mygraph->table = newtable;
mygraph->MaxSize = newmaxsize;
};
mygraph->table[n].name = strdup(name);
mygraph->table[n].outdegree = 0;
}
您可能不需要insert_node
返回值(否则,您将不会总是返回0)。 因此,我将其void
返回函数(即“过程”或“例程”)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.