【问题标题】:Inserting a node in a linked list在链表中插入一个节点
【发布时间】:2018-04-19 02:14:36
【问题描述】:

我有这个练习,要求我创建一个函数,该函数根据包含一个整数的结构将新节点中的数字添加到链表的头部。这是结构:

struct Node
{
    int data;
    struct Node *next;
};

到目前为止没问题。所以我创建了一个带有 2 个参数的参数:要添加的整数和指向链表头部的指针,但它不起作用。这是我的代码:

void push(struct Node* head, int new_data)
{
    struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));

    new_node->data = new_data;

    new_node->next = head;

    head = new_node;
}

所以,我所做的就是让 new_node 指向 head 指向的同一个节点,然后我将新节点设为链接的新头列表。这似乎很合乎逻辑,虽然它没有工作。另一方面,当我给函数提供 head 指针的地址而不是指针本身时,它确实有效:

void push(struct Node** head_ref, int new_data)
{
    /* 1. allocate node */
    struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));

    /* 2. put in the data  */
    new_node->data  = new_data;

    /* 3. Make next of new node as head */
    new_node->next = (*head_ref);

    /* 4. move the head to point to the new node */
    (*head_ref)    = new_node;
}

这是双**的主要功能:

int main()
{
    struct Node* head = NULL;
    push(&head,7);
    push(&head,6);
    push(&head,3);
    return 0;
}

我知道第二个功能应该可以工作,但我不明白为什么需要使用 head 的地址而不是 head 本身。如果有人能向我解释原因,我会很高兴,谢谢。

【问题讨论】:

  • 在C++中有containers
  • 1) std::list & std::forward_list 已经存在 - 使用它们。 2) 对于现代计算机而言,链表通常是一种可怕的数据结构(std::vector 几乎总是更好的选择。
  • 选择一种语言,C 或 C++。
  • @Paul @Bilal 通过删除任何初始标签来使现有答案无效并不是很好。虽然我的回答仍然涵盖了你问题的 c 部分。

标签: c algorithm data-structures linked-list


【解决方案1】:

但我不明白为什么必须使用 head 的地址而不是 head 本身。

在普通的 代码中,您不能有引用(与 c++ 相比),只能有指针。

head 指针变量中存储的值应从调用内部更改为push(),因此您需要传递head 变量的地址来更改(单*指针)值。

int main()
{
    struct Node* head = NULL;
    push(&head,7);
    // ...
}

void push(struct Node** head_ref, int new_data)
{

    // ...

    /* 3. Make next of new node as head */
    new_node->next = (*head_ref); // Dereferencing head_ref yields the current 
                                  // content of head

    /* 4. move the head to point to the new node */
    (*head_ref)    = new_node; // Store the newly allocated memory address
                               // into the head pointer
}

当您标记您的问题 时,最初这不是使用 c++ 代码所必需的。

你也可以通过引用来获取指针参数:

void push(struct Node*& head_ref, int new_data)
                   // ^
{
    // ...

    /* 3. Make next of new node as head */
    new_node->next = head_ref;

    /* 4. move the head to point to the new node */
    head_ref = new_node; // <<<<<<<<<<
}

int main() {
    struct Node* head = nullptr;
    push(head,7);
    push(head,6);
    push(head,3);
    return 0;
}

【讨论】:

  • 对指针的引用不是很 C++,但在这种情况下它可以工作。
  • 我明白了,但是在C语言的情况下,它就变得必要了。我的问题是为什么会这样,在上面的这种情况下。我不是在寻找解决问题的新技巧,但我想了解使用指针地址时发生了什么,而仅使用指针时不会发生。
  • @BilalEnnouali “但我想了解在使用指针地址时发生了什么” 抱歉,我以为我已经解释得很好了。传递指针变量的地址允许您更改指针值。否则,您只需修改指针值的副本,并且您的修改不会影响函数之外的任何变量。
  • @BilalEnnouali -- 指针就是一个值。您将值传递给函数,该值在该函数中是临时的。如果您希望将更改反映回调用者,则传递一个指向该值的指针。因此,如果您想更改该指针的值(同样,指针就是一个值),您需要将一个指针传递给该指针。
猜你喜欢
  • 1970-01-01
  • 2020-11-15
  • 2015-02-08
  • 1970-01-01
  • 2011-12-23
  • 1970-01-01
  • 2018-07-28
相关资源
最近更新 更多