C中的循环链表没有给出所需的输出

cHa*_*Ham 1 c pointers linked-list

我想在C中制作一个循环链表,但我遇到了一些麻烦.我很确定这是一个指针问题(我正在学习C和指针是一个弱点).这是代码:

#include <stdio.h>
#include <stdlib.h>
#include "cl.h"

nodeptr add_to_end(nodeptr head, int val)
{
    if (head == NULL)
    {
        nodeptr new_node = (nodeptr)malloc(sizeof(node));
        new_node->data = val;
        new_node->next = NULL;
        return new_node;
    } else {
        head->next = add_to_end(head->next,val);
        return head;
    }
}


void print_piles(nodeptr nodeHead)
{
    if (nodeHead == NULL)
        return;
    printf("%d\n ",nodeHead->data);
    print_piles(nodeHead->next);
}



int main(int argc, char *argv[])
{
    nodeptr head = NULL;
    nodeptr tail = NULL;
    int i = 0;

    head = add_to_end(head,i);
    i++;
    tail = add_to_end(tail,i);
    head->next = tail;
    i++;
    tail = add_to_end(tail,i);
    tail->next = head;

    printf("%d\n ",head->data);
    printf("%d\n ",tail->data);
    tail = tail->next;
    printf("%d\n ",tail->data);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

从cl.h:

// create struct for cards in piles
;typedef struct node
{
    int data;
    struct node *next;
}node, *nodeptr;
Run Code Online (Sandbox Code Playgroud)

输出是:

0
1
0
Run Code Online (Sandbox Code Playgroud)

我期望得到的是:

0
1
2
Run Code Online (Sandbox Code Playgroud)

我需要改变什么?

Gri*_*han 5

不是指针问题!您正在获得定义的行为.但你循环链接的步骤是错误的.阅读下面我解释了你的main()功能步骤:

步骤1:

i = 0;
head = add_to_end(head,i);
Run Code Online (Sandbox Code Playgroud)

所以创建了一个head节点(假设节点地址是201):

head: 201
[ 0, NULL]
Run Code Online (Sandbox Code Playgroud)

第2步:

i++;
tail = add_to_end(tail,i);
Run Code Online (Sandbox Code Playgroud)

所以创建了一个tail节点(假设节点地址是304):

tail: 304
[ 1, NULL]
Run Code Online (Sandbox Code Playgroud)

第3步:
赋值后 head->next = tail;:链表如下:

head: 201     tail: 304 
[ 0, 304] --? [1, NULL]
Run Code Online (Sandbox Code Playgroud)

步骤4: 遵循两个代码序列:

i++;
tail = add_to_end(tail,i);
Run Code Online (Sandbox Code Playgroud)

您已2在链接列表中创建了一个新节点和附加节点的值(假设为地址349),列表如下所示:

head: 201     tail: 304         : 349
[ 0, 304] --? [ 1, 349] --? [ 2, NULL]
Run Code Online (Sandbox Code Playgroud)

第5步:
现在错误:tail值仍然是304根据你的添加功能,所以在最后一次分配后,tail->next = head;你得到如下所示:

head: 201     tail: 304         : 349
[ 0, 304] --? [ 1, 349]    [ 2, NULL]
   ?             |
   +-------------+  
Run Code Online (Sandbox Code Playgroud)

所以next of tail is head这就是你获得0, 1, 0输出的原因.

还要注意你有内存泄漏!

为什么会这样?add函数最后追加一个节点并返回head传递给你传递的函数tail(我正在评论).

nodeptr add_to_end(nodeptr head, int val)
{                     //    ^ is tail at third call
    if (head == NULL)// if first node is NULL
    {
        nodeptr new_node = (nodeptr)malloc(sizeof(node));
        new_node->data = val;
        new_node->next = NULL;
        return new_node; <-- "return only if new node is first node"
    } else {
        head->next = add_to_end(head->next,val);
        return head; <--- "Return `head` that is passed to function at calling"
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,当您调用tail = add_to_end(tail, i);where tailnot not NULL时,函数add_to_end返回较旧的tail(在我的示例地址中为304).

你应该纠正tail->next = head;tail->next->next = head;,你会得到的结果除外.