【问题标题】:Why aren't nodes adding properly and why is it printing in reverse? (singly linked list)为什么节点没有正确添加,为什么它反向打印? (单链表)
【发布时间】:2019-09-14 08:01:32
【问题描述】:

已解决

这个问题也可以通过在添加新节点后将头部复制到另一个变量中来解决。 一个更合乎逻辑的解决方案是按照答案所说的那样做。



我正在练习一个简单的链表实现,也想更多地探索指针。为什么我的代码没有正确添加节点?

typedef struct Node{

    int info;

    struct Node* next;

}Node;

void createList(Node** node, int info){

        *node = calloc(1, sizeof(Node));
        (*node)->info = info;
        (*node)->next = NULL;

}
Node* newNode(int info)
{
    Node* newNode;
    newNode = calloc(1, sizeof(Node));
    newNode->info = info;
    newNode->next = NULL;

    return newNode;
}

void addNode(Node** node, int info){
    int adaugat = 0;


    if(*node == NULL){

        createList(node, info);
        adaugat = 1; 
    }

    if(adaugat == 0)
    {
        Node **aux = node;
        while((*aux)->next != NULL)
        {
            *aux = (*aux)->next;
        }
        (*aux)->next = newNode(info);
        adaugat = 1;
    }

}
void printList(Node* node){
    int i = 1;
    Node* aux;
    aux = node;
    while(aux != NULL)
    {
        printf("%d_[%d]--",i, aux->info );
        i++;
        aux = aux->next;
    }
}
int main(int argc, char const *argv[])
{
    Node *nod = NULL;
    int key = 5;

    createList(&nod, key);

    addNode(&nod, 5);
    addNode(&nod, 3);
    addNode(&nod, 4);
    addNode(&nod, 1);

    printList(nod);

    return 0;
}

我尝试在 main() 中使用指针和函数调用输入进行转换,但我得到的只是更多的警告和段错误。 main() 的输出是 1_[4]--2_[1]--,而它应该是

1_[5]--2_[3]--3_[4]--4_[1]--

【问题讨论】:

  • 为什么链表的头部需要一个额外的节点? Node *nod 已经是头部,所以 createList() 是多余的。一个简单的链表就像一个 LIFO 堆栈:这就是打印顺序相反的原因。
  • createList() 同时充当 Init,您是否建议这种方法导致我出现问题?虽然我从头开始打印,但我不明白为什么它是反向的......
  • 哦,我明白了,您正在尝试将每个项目添加到列表的尾部。在一个简单的列表中,您在前面添加每个新项目。整个事情似乎过于复杂。
  • 添加到列表尾部不起作用?在我大学的实验室里,IIRC 所有的简单链表都是从头到尾添加的。这项工作对我来说是一个小测试,因为我一直在使用现成的填充空白 .h 文件,并带有一个大的测试 .c 文件。需要新鲜的东西。
  • 对我来说,如果您必须解析整个列表以添加新项目,那么它就违背了链表的意义。如果您希望它们反过来,请以相反的方式插入它们。

标签: c pointers linked-list segmentation-fault singly-linked-list


【解决方案1】:

在函数addNode的这个sn-p中

if(adaugat == 0)
    {
        Node **aux = node;
        while((*aux)->next != NULL)
        {
            *aux = (*aux)->next;
        }
        (*aux)->next = newNode(info);
        adaugat = 1;
    }

更准确地说,在*aux = (*aux)->next; 行上,由于Node ** aux,您正在移动列表的同时您正在遍历它。因此,您的列表看起来总是有两个元素。

如果要在列表末尾添加一个元素,则必须遍历列表而不修改它,即

if(adaugat == 0)
    {
        Node *aux = *node;
        while(aux->next != NULL)
        {
            aux = aux->next;
        }
        aux->next = newNode(info);
        adaugat = 1;
    }

【讨论】:

  • 谢谢!我能够修复它。在添加任何节点之前,我只是在创建列表时复制了 head。
  • 很抱歉撤销接受,我太快接受并遇到问题。但事实证明这只是我的错。再次感谢!
【解决方案2】:

问题出在下面的代码块

    if(adaugat == 0)
    {
        Node **aux = node;
        while((*aux)->next != NULL)
        {
            *aux = (*aux)->next;
        }
        (*aux)->next = newNode(info);
        adaugat = 1;
    }

变量node 没有被取消引用,因此这里不需要使用双指针。将该部分更改为以下内容将为您提供所需的输出...


    if(adaugat == 0)
    {
        Node *aux = *node;
        while(aux->next != NULL)
        {
            aux = aux->next;
        }
        aux->next = newNode(info);
        adaugat = 1;
    }

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-07
    • 2020-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2014-04-22
    • 1970-01-01
    相关资源
    最近更新 更多