当我修改链接列表时,为什么需要指定链接列表?

时间:2014-11-24 22:40:40

标签: c linked-list

在此代码中:

void push(node **head, int data) {
    node *temp = malloc(sizeof(node));
    temp->data = data;
    temp->next = *head;
    *head = temp;
}

为什么temp->next = *head不够?

为什么有必要将*head设为temp?这完成了什么?

3 个答案:

答案 0 :(得分:2)

方法push()有两个参数:指向node指针的指针(指向链表的指针)和要插入列表的值。

需要*head = temp;的原因是调用者的链接列表最终被修改。如果没有此行,则不会修改调用者的链接列表。

这是一个高度简化的例子,说明为什么这是必要的。假设我有一个修改int的方法:

void foo(int *bar) {
    int baz;
    baz = *bar;
    baz = 42;
}

通过传入指针调用foo()后,指针指向的变量不会发生任何事情。当foo()完成时,所有堆栈变量(即barbaz)将不再存在,并且永远不会保存对bar的值的修改。 / p>

回到你问题中的例子。如果该行永远不会被调用,那么调用者的副本就会发生 nothing (即在调用该函数之后,就好像该元素从未被添加到列表中),原因与调用者的副本相同传入foo()的任何内容都没有改变。

出于这个原因,您经常会看到insert()函数的不同方法签名:

node *push(node *head, int data);

这就像这样调用:

// assume head is a pointer to a node
head = push(head, 42);

效果是一样的,但是因为只有一个指向节点的指针被传入,所以push()对列表结构所做的任何操作都不会应用于head,直到进行赋值。

答案 1 :(得分:1)

它将头部重置为新节点,允许我们迭代所有元素。 Push将新节点放在列表的开头。 Head就像链接列表的起点,使用它可以获得所有元素。如果磁头未设置为新节点,则将丢失对新插入数据的引用,从而导致内存泄漏。

答案 2 :(得分:0)

假设它是一个基于列表的堆栈(根据Push操作猜测),那么该项应该添加到列表的开头,以便可以轻松弹出。 这样,当调用者再次尝试使用堆栈时,列表的头部将使用新数据项进行更新。