简体   繁体   English

有向图的C输入

[英]C Input for Directed Graphs

We are told our input file would be a simple list of numbers: 我们被告知输入文件将是一个简单的数字列表:

1 3 4 1 3 4

2 3 2 3

3 4 3 4

4 1 2 4 1 2

Where the first number is the source node, and the proceeding numbers are it's adjacent nodes. 其中第一个数字是源节点,而后续的数字是它的相邻节点。

I am trying to figure out how to best store this. 我试图弄清楚如何最好地存储它。 I wanted to firstly initialize a "graph", an array that contains all these nodes. 我想首先初始化一个“图形”,一个包含所有这些节点的数组。 Then upon reading the file, line by line, I would store the root node into the graph array, and then update the node's outlist (adjacent nodes) with the following numbers until we reach the end of the line, repeating this for each line until EOF. 然后,逐行读取文件后,我会将根节点存储到图数组中,然后使用以下数字更新该节点的列表(相邻节点),直到到达行尾为止,对每行重复此操作,直到EOF。

However I'm struggling on how to initialize the graph, do I just assume a certain size and realloc() once the size is hit? 但是我在如何初始化图形上苦苦挣扎,我是否只是假设一定的大小并在达到大小后立即重新分配()? Do I read the file first and count the number of lines to find out the size, then re-read the file to store the nodes? 我是否首先读取文件并计算行数以找出大小,然后重新读取文件以存储节点? Is there any other way? 还有其他办法吗?

Here is the code for my data structures: 这是我的数据结构的代码:

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;
}

So upon reading the file, 因此,在读取文件后,

  1. I initialize the graph. 我初始化图。

  2. I read the first number, store it as a new graph node. 我读取了第一个数字,并将其存储为新的图形节点。

  3. I read the next numbers until hitting "\\n", and store these as graph links to the above root node. 我阅读下一个数字,直到打到\\ n,然后将它们存储为指向上述根节点的图形链接。

  4. I do this for each line until hitting EOF. 我会针对每一行执行此操作,直到达到EOF。

As you can see I have no idea what the "MaxSize" until the whole file is read. 如您所见,在读取整个文件之前,我不知道“ MaxSize”是什么。

Thanks! 谢谢! I'm rather new to C so sorry if I've done anything silly. 我对C相当陌生,所以如果做任何愚蠢的事,我都感到抱歉。

You could have some initial guess for MaxSize (eg 8) and grow when needed your data (perhaps by graph->MaxSize += graph->MaxSize/2 ) using realloc , or just by malloc -ing a bigger new chunk, copying the older chunk inside, then free -ing that older chunk). 你可以有一些初步猜测MaxSize (例如,8),需要你的数据(可能是当成长graph->MaxSize += graph->MaxSize/2 )使用realloc ,或只是malloc -ing一个更大的新块,复制里面的旧块,然后free该旧块)。 Don't forget to check the successful result of any malloc or calloc or realloc call, they could (rarely) fail. 不要忘记检查任何malloccallocrealloc调用的成功结果,它们可能(很少)失败。

Notice that I have no idea of how your Graph and Node type is declared (just guessing). 注意,我不知道如何声明您的GraphNode类型(只是猜测)。

I am assuming and guessing you have declared something like 我假设并猜测您已经声明了类似

 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
 };

So for example your insert_node function might be 因此,例如您的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;
}

You probably don't need insert_node to return a value (otherwise you won't always return 0). 您可能不需要insert_node返回值(否则,您将不会总是返回0)。 So I made it a void returning function (ie a "procedure" or "routine"). 因此,我将其void返回函数(即“过程”或“例程”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM