在第二个位置c ++中插入列表

时间:2016-11-19 12:03:32

标签: c++

我想在列表中插入一个元素作为第二个元素,创建一个新列表而不修改原始列表。

实施例: list 1 2 3 4 5,cin>> 55,然后新的名单变成1 55 2 3 4 5.

问题是两个列表都被修改了。为什么会这样?

ptr_list insertAfterFirstElem(ptr_list head){
    ptr_list tmp;
    tmp=new list;
    cout<<"Insert value"<<endl;
    cin>>tmp->val;
    tmp->next=head->next;
    head->next=tmp;
    return (head);

}

我编写了一个工作正常的insertAtTop函数:

ptr_list insertAtTop(ptr_list head){
    ptr_list tmp;
    tmp=head;
    head=new list;
    cout<<"Insert value"<<endl;
    cin>>head->val;
    head->next=tmp;
    return (head);

}

你能解释一下这两个功能有什么区别吗?为什么insertAtTop()不修改原始列表?

1 个答案:

答案 0 :(得分:0)

两个列表共享相同的单元格;这就是你遇到麻烦的原因。

head: xxx -> yyy -> zzz -> ttt
       ^
res: --|

如果tmp = uuu,则将其插入第二个位置

head: xxx -> uuu-> yyy -> zzz -> ttt
       ^      ^
res: --|      |-- tmp

但是,正如您所看到的,从head开始的原始列表也会被修改。

如果您不想修改它,则需要在插入前复制原始列表:

head: xxx -> yyy -> zzz -> ttt
copy: xxx -> yyy -> zzz -> ttt
       ^
res: --|

然后你可以插入

head: xxx -> yyy -> zzz -> ttt
copy: xxx -> uuu-> yyy -> zzz -> ttt
       ^      ^
res: --|      |-- tmp

可能的解决方案可能是:

ptr_list copyList(ptr_list head) {
    ptr_list copy = nullptr;
    ptr_list* copy_last = &copy;
    for (ptr_list iter = head; iter != nullptr; iter = iter->next) {
      *copy_last = new list(*iter);
      copy_last->val = iter->val;
      copy_last->next = nullptr;
      copy_last = &copy_last->next;
    };
    return copy;
}

ptr_list insertAfterFirstElem(ptr_list head){
    ptr_list copy = copyList(head);
    ptr_list tmp;
    tmp=new list;
    cout<<"Insert value"<<endl;
    cin>>tmp->val;
    tmp->next=copy->next;
    copy->next=tmp;
    return (copy);
}

现在使用insertAtTop(ptr_list head)您仍然遇到共享问题,但您不会立即看到它。它创建了

    head: xxx -> yyy -> zzz -> ttt
           ^
res: uuu --|

因此,如果过了一段时间,您想在head的第二个位置插入另一个单元格,您也会修改结果。

没有任何insertAtTop份额的实施是

ptr_list insertAtTop(ptr_list head){
    head = copyList(head);
    ptr_list tmp;
    ...
}

也不要忘记释放细胞。如果您不使用reference-counting之类的其他机制,则几乎不可能通过共享释放。