【问题标题】:Adding to the front of a Linked List in C在 C 中添加到链表的前面
【发布时间】:2016-09-05 13:33:26
【问题描述】:

我在理解一般的链表时遇到了困难。我了解它们是如何在纸上工作的,但是一旦我开始编写它们,我似乎永远不会完成任何事情。

这是我的代码:

头文件:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct List {

    int data;
    struct List * next;
} List;

实现文件:

#include "test.h"

void addToFront(int data, List * head);

int main(void) {
    List * list;
    list = malloc(sizeof(List));
    list->next = NULL;

    List * head;
    head = NULL;

    addToFront(5,head);

    printf("%d",head->data); //print first element
    printf("%d",list->data); //print first element

}

void addToFront(int data, List * head) {
    if(head == NULL) {
        List * newNode = malloc(sizeof(List));
        newNode->data = data;
        head = newNode;
    }
    else {
        List * newNode = malloc(sizeof(List));
        newNode->data = data;
        newNode->next = head;
        head = newNode;
    }

}

我知道如果一个链表是空的,标题是NULL,所以我在那里检查了。当我收到一个段错误说标头未初始化时,问题就出现了,显然不是,如果我进行了初始化,我无法跟踪列表是否为空,因此使用了标头节点。

我现在能做什么?我不想使用双指针,因为到目前为止,我的班级还没有其他人在使用它们(请不要让我使用双指针),我完全不知道如何在这里继续。

我正在考虑在没有标头节点的情况下尝试此操作。因此,我可以有一个计数器来跟踪列表中的项目,检查它是否为零,然后将基本元素添加到前面,否则做我在 else 语句中做的同样的事情?

【问题讨论】:

    标签: c pointers memory data-structures linked-list


    【解决方案1】:

    问题出在你的addFront函数中,你只传递了head的指针,为了改变head指向的东西你需要传递head的地址:

    void addToFront(int data, List ** head) 
    

    然后

    *head = newHead
    

    当您只传递指针时,您只是将指针的副本传递给函数,因此一旦离开函数范围,您在函数内对指针所做的任何更改都会丢失。

    在概念上类似于:

    void f(int n)
    {
      n = 53;
    }
    

    为避免双指针,您可以返回新的头:

    List* addToFront(int data, List* head)
    {
      ...
      return newNode;
    }
    
    ...
    
    head = addToFront(data, head);
    
    ...
    

    【讨论】:

    • 在使用链表时,有没有办法避免使用双指针?
    • 您可以返回指针,而不是使用双指针,这样您就可以更改它。例如List* addToFront(int data, List* head);
    • 你可以有一个包含头部、尾部和大小的结构。因此,当您将指针传递给它时,内部指针修改将是有效的。 (假设此结构名称为 List 并且您当前的 List 结构重命名为 ListNode)
    • @Terzig 没错,你可以通过多种方式解决这个问题:)
    【解决方案2】:

    如果不想使用双指针,可以将头节点作为哨兵节点,仅作为占位符,让第一个元素通过head-&gt;next链接,并检查列表是否为空,请查看head-&gt;next == NULL。试试这个:

    int main(void) {
        List *head = malloc(sizeof(List));
        head->data = 0;
        head->next = NULL;
    
        addToFront(5, head);
    
        List *first = head->next;
        if (first) { // safe guard for first element
            printf("%d", first->data); //print first element
            printf("%d", first->data); //print first element
        }
    }
    
    void addToFront(int data, List * head) {
        List * newNode = malloc(sizeof(List));
        newNode->data = data;
        newNode->next = head->next;
        head->next = newNode;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-06-01
      • 1970-01-01
      • 2011-06-20
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      相关资源
      最近更新 更多