Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么需要一个双指针来更改head而不是链接列表中的其他位置_C++ - Fatal编程技术网

C++ 为什么需要一个双指针来更改head而不是链接列表中的其他位置

C++ 为什么需要一个双指针来更改head而不是链接列表中的其他位置,c++,C++,我不明白为什么需要使用指向指针的指针来更改头部,但如果要在其他位置添加元素,只需发送node*head,而不是node**head。类似于insertAtTopnode*head作为参数工作,但如果我对insertAtTop做了同样的操作,则不会。通过使用按引用传递和按值传递可以同时实现insertAtTop。我建议你读书。你也可以阅读 我假设head被声明为node*head 通过引用传递: void insertAtTop(node** head, int value){ node*

我不明白为什么需要使用指向指针的指针来更改头部,但如果要在其他位置添加元素,只需发送
node*head
,而不是
node**head
。类似于
insertAtTop
node*head
作为参数工作,但如果我对
insertAtTop
做了同样的操作,则不会。

通过使用
按引用传递
按值传递
可以同时实现
insertAtTop
。我建议你读书。你也可以阅读

我假设
head
被声明为
node*head

通过引用传递:

void insertAtTop(node** head, int value){
    node* temp=new node();
    temp->data=value;
    temp->next=*head;
    *head=temp;
}

void insertAtLast(node*head, int value){
    while(head->next!=NULL){
        head=head->next;
    }
    node*temp=new node();
    temp->data=value;
    temp->next=NULL;
    head->next=temp;
}
void insertAtLast(node** head, int value){
    node* h = *head;
    while(h->next!=NULL){
        h = h->next;
    }
    node* new_node=new node();
    new_node->data=value;
    new_node->next=NULL;
    h->next=new_node;
}
调用:
insertAtTop(&head,value)

调用:
insertaltlast(&head,value)

传递值:

void insertAtTop(node** head, int value){
    node* temp=new node();
    temp->data=value;
    temp->next=*head;
    *head=temp;
}

void insertAtLast(node*head, int value){
    while(head->next!=NULL){
        head=head->next;
    }
    node*temp=new node();
    temp->data=value;
    temp->next=NULL;
    head->next=temp;
}
void insertAtLast(node** head, int value){
    node* h = *head;
    while(h->next!=NULL){
        h = h->next;
    }
    node* new_node=new node();
    new_node->data=value;
    new_node->next=NULL;
    h->next=new_node;
}
调用:
head=insertatop(head,value)


调用:
head=insertlast(head,value)

您不必使用双指针。请参阅下面的代码:

node* insertAtLast(node* head, int value){
    node* original_head = head;
    while(head->next!=NULL){
        head=head->next;
    }
    node*temp=new node();
    temp->data=value;
    temp->next=NULL;
    head->next=temp;
    return original_head;
}

使用双指针时,将指针传递给指针。当您只有一个指针时,取消对它的引用会给出变量的值。使用双指针,解引用将为您提供内存中变量的地址。当您将节点添加到列表的前面时,您将获取已经为head节点创建的节点,并传入指向它的指针的地址。为了添加到链表的头部,你必须这样做的原因是,你已经在内存中的某个地方有了一个指向链表头部的引用,因为链表结构被定义为有一个最初指向null的头部节点,随后添加到链表前面的节点将改变查找位置链接列表的开始

两者都有一个双指针。从两个函数中看这两条类似的线:

node* front(int n, node* head)
{
    node *tmp = new node;
    tmp -> data = n;
    tmp -> next = head;
    head = tmp;
    return head;
}
请注意,
head->next=temp
可以等效地写成
(*head)。next=temp

那里有一个“双指针:
head
是指向结构的指针,该结构包含一个指针
next
。基本上这两幅图:

*压头=温度的示意图

*head=temp;  // from insertAtTop

head->next=temp; // from insertAtLast
head->next=temp
(*head.)的图表。next=temp
。例如,节点结构表示为三个存储单元,其中第三个是
next
字段。确切的内存细节取决于编译器和定义结构的方式

head --> [ *--]---> old_head
            ^
            `-- temp is stored here, replacing the old_head
基本上,唯一的区别是我们有一个结构,而不仅仅是一个指针对象

在这两种情况下,都会更新指针以引用新插入的节点。在
insertAtTop
案例中,我们必须替换表示列表本身的指针。我们将列表对象表示为指向第一个节点的指针。如果更改列表以使其具有不同的第一个节点,则该指针必须更改。在列表中的其他位置插入时,我们必须更新上一个节点的
next
指针以指向新节点,因此我们将指定给
(*head).next

我们可以重写
insertAtLast
以将
insertAtTop
用作子例程:

head  --> [    ]
          [    ] 
          [ *--]--> old_next
             ^
             `-- temp is stored here, replacing old_next
如果您跟踪调用
insertatead
时发生的情况,您会发现它所做的事情与我们替换的代码完全相同。我们删除了以下代码:

node* insertAtLast(node* head, int value){
    /* find the insertion point */
    node* original_head = head;
    while(head->next!=NULL){
        head=head->next;
    }
    /* now treat that as the head */
    (void) insertAtTop(&head->next, value);
    return original_head;
}
但这几乎与
insertatead
的主体相同,即:

    node* new_node=new node();
    new_node->data=value;
    new_node->next=NULL;
    h->next=new_node;
我们将表达式
&h->next
的值作为
head
参数传递。所以
temp->next=*head
实际上是
temp->next=*&h->next
中的
*&code>取消,留下
temp->next=h->next
。但是我们知道
h->next
NULL
:我们的
while
循环确保了这一点。这就是有效的
temp->next=NULL

当然,
*head=temp
*(&h->next)=temp
相同,即
h->next=temp

相关/重复:在
c++
中,应该使用
void insertatop(node*&head,int-value){
相反。我不明白为什么需要使用指向指针的指针来更改标头,但如果要在其他位置添加元素,只需发送
node*
head而不是
node**
head即可。使用
node*
时,您是按值传递指针。传递值时,它是一个副本。更改副本对调用函数没有影响。请查看调用代码。您传入了一个头指针。在前面插入一个新节点后,应该是什么?如果在头之后插入一个新节点,情况是否相同?注意。这是使用sentinel节点(下一个=头)的原因之一可以很好:它使大多数操作(包括此操作)更加规则,具有更少的特殊角盒。请尝试Ram。但是对
head
内部
front()
所做的更改将只保留在
front()
中。从
front()返回后,这些更改将不会保留
。哦,是的,我的错!你应该把脑袋还给我吗?是的。请看看我的答案。
   node* temp=new node();
   temp->data=value;
   temp->next=*head;
   *head=temp;