You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无表头链表队列enqueue函数中Node**双指针的作用与含义解析

理解无表头链表队列中的Node **list双指针

先明确:Node **list是指向指针的指针,用它的核心原因是C语言的参数传递是「值传递」——如果函数要修改调用者传入的指针变量本身(而不是指针指向的内容),就必须传这个指针的地址,也就是指针的指针。

为什么必须用双指针?

假设我们不用Node **list,而是用Node *list作为enqueue的参数:

  • 当队列为空时,函数里给list赋值new,但这个list只是原头指针的一个副本,修改副本不会影响调用者那边的原头指针。函数结束后,外面的头指针还是NULL,新节点根本没被正确关联到队列上,队列等于白初始化了。

而用Node **list时,*list就直接对应调用者那边的头指针变量:

  • 队列为空时,*list = new直接把调用者的头指针改成指向新节点,这样外部的队列头指针就正确指向了第一个节点。
  • 非空时,new = *list拿到队列的头指针副本,遍历到链表尾部后调用insertNode插入新节点,这时候虽然没修改头指针,但通过*list能正确访问到队列的起始位置。

结合代码细节解释

补全必要定义后的完整代码示例:

#include <stdlib.h>

typedef struct Node {
    int val;
    struct Node *next;
} Node;

// 判断队列是否为空
int isEmpty(Node *list) {
    return list == NULL;
}

void insertNode(Node * prev,int x) {
    Node * new = (Node *) malloc(sizeof(Node));
    new->val = x;
    new->next = prev->next;
    prev->next = new;
}

void enqueue(Node ** list, int x) {
    Node * new = (Node *) malloc(sizeof(Node));
    if (isEmpty(*list)) {
        *list = new;
        (*list)->val = x;
        (*list)->next = NULL;
    }
    else {
        new = *list;
        while (new->next != NULL) 
            new = new->next;
        insertNode(new,x);
    }
}
  • isEmpty(*list):这里*list取出双指针指向的内容,也就是队列的头指针,判断是否为空。
  • *list = new:直接修改调用者的头指针变量,让它指向新创建的节点,完成空队列的初始化。
  • 非空分支里,new = *list拿到头指针的副本,遍历到链表最后一个节点,然后调用insertNode在尾部插入新节点——这时候只修改尾部节点的next,不需要改动头指针,但双指针的传递方式保证了我们能正确获取队列的起始位置。

总结一下:Node **list的作用就是让函数能够修改调用者那边的队列头指针变量,这是无表头节点链表队列初始化时必须的操作,因为空队列的头指针是NULL,第一次入队必须把它改成指向第一个节点。

内容的提问来源于stack exchange,提问作者dev0419

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 21:50:38