一个节点,其自身位于其邻接列表中

时间:2011-12-14 12:50:16

标签: c graph linked-list adjacency-list

typedef struct vertex{
    int num;
    struct vertex *next;
} Vertex;

Vertex *adj[1];

void buildList(){
    Vertex *v=NULL;
    Vertex *t=NULL;

    v = malloc(1*sizeof(*v));
    v->num = 1;
    adj[0] = v;  //a NODE with value 1
    t = v;

    v = malloc(1*sizeof(*v));
    v->num = 1;
    t->next = v; // and ANOTHER NODE but it should be the SAME NODE with the above one
    t = v;


    //v = malloc(1*sizeof(*v));
    //v->num = 1;
    //t->next = adj[0]; // causes infinite loop...
    //t = v;
}

预期输出是值为1的节点,其自身在其邻接列表中,输出如1 - > 1。

这里我的问题是看起来我有两个不同的节点。当我对其中一个进行更改时,另一个不会更改,就像另一个节点一样。

例如,在构建列表后,如果我更改节点的值,我应该得到类似3的输出 - >但是我得到3 - > 1.节点上的更改不会影响另一个节点。当我尝试将adj [0]指向t->然后我得到一个无限循环......

5 个答案:

答案 0 :(得分:2)

我不清楚你想要什么。如果你想要一个Vertex指向它自己,它就是

void buildList(){
    adj[0] = malloc(1*sizeof(*adj[0])); // allocate memory for one Vertex
    if (adj[0] == NULL){
        perror("Allocation of Vertex failed\n");
        exit(EXIT_FAILURE);
    }
    // adj[0] contains the adress of a Vertex
    // set the num of the Vertex
    adj[0]->num = 1;
    // set the next pointer of the Vertex to its address
    adj[0]->next = adj[0];
}

你能澄清一下这不是你想要的吗?

答案 1 :(得分:1)

你可以毫无疑问地想要输出,但这不会让它成为现实。

你很清楚地创建了两个节点,令人困惑地重复使用v这样做。

我不确定你要做什么;但清理代码以消除阅读t = v;的两行可能会澄清你的情况。

如果你希望v->next指向自己,你需要做到这一点。如果您想要一个节点,则必须构建代码,以便malloc()只调用一次。

请记住Vertex *v;没有声明顶点;它声明了一个指向顶点的指针。

答案 2 :(得分:1)

您应该提供整个代码,以了解您如何使用该功能和列表。实际错误可能在其他地方。 如果达到列表末尾,你如何比较?

通常,链表的最后一个节点的next指针被指定为NULL。这不太可能导致无限循环。


通常你会做这样的事情:

void buildList(){
  // the list base
  adj[0] = malloc(1*sizeof(*v));
  adj[0]->num = 1;
  adj[0]->next = adj[0]; // <-- make the last node point to itself

  // append more items to the end of the list
  Vertex *v=adj[0];
  while (v != v->next) v = v->next; // <-- find the end of the list
  int i;
  int num_nodes = 1; // <-- specify the number of nodes you want in total
  for (i = 1; i < num_nodes; i++) {
    // append another item
    v->next = malloc(1*sizeof(*v)); 
    // initialize it
    v = v->next;
    v->num = i; 
    v->next = v; // <-- make the last node point to itself
  }
}

而您描述的无限循环可能来自于您将列表库分配到列表末尾的事实。从而有效地使列表成为一个循环。

答案 3 :(得分:1)

您可以按如下方式分析代码段:

    你通过mallocing分配指针v。并为其赋值为1.注意指向下一个元素的指针,v-&gt; next是未初始化的
      然后你将v复制到adj [0]和t。并且再次重新初始化v,(我认为这是多余的),设置其值并将其值复制到t-&gt; next
      到目前为止,你必须指向自己,即1点到1点。但是当你再次将t重新初始化为v时,具有v->接下来未初始化的v会导致t->旁边也是未初始化的,因此指向iyself的变量现在不可能
      在代码的注释部分,同样的事情发生,因为adj [0]是v .So关于无限循环,这是由于你在工作中使用上述代码片段,当单独运行时会给你一个细分访问t-&gt; next
    时出错

答案 4 :(得分:0)

已经提供的代码看起来就像创建了两个独立的节点,稍后您只需重新分配节点t = v,这使得指针只指向一个节点。

节点1的备份,在阵列上并不清楚它们背后的原因。

如果你能解释你想要实现的逻辑,那将是件好事。