我想在列表中插入一个元素作为第二个元素,创建一个新列表而不修改原始列表。
实施例: 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()不修改原始列表?
答案 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 = ©
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 = ©_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之类的其他机制,则几乎不可能通过共享释放。