void delself(list *list)
{
/*if we got a pointer to itself how to remove it...*/
int n;
printf("Enter the num:");
scanf("%d",&n);
while(list->next!=NULL)
{
if(list->number==n) /*now pointer in node itself*/
{
list->number=list->next->number; /*copy all(name,rollnum,mark..)
data of next to current, disconnect its next*/
list->next=list->next->next;
}
list=list->next;
}
}
4
如果你有一个链表A - > B - > C - > D和一个指向节点B的指针 . 如果你必须删除这个节点你可以将节点C的内容复制到B,节点D复制到C并删除D.但是我们不能在单链表的情况下删除节点,因为如果我们这样做,节点A也将丢失 . 虽然我们可以在双链表的情况下回溯到A.
我对吗?
0
void delself(list *list)
{
/*if we got a pointer to itself how to remove it...*/
int n;
printf("Enter the num:");
scanf("%d",&n);
while(list->next!=NULL)
{
if(list->number==n) /*now pointer in node itself*/
{
list->number=list->next->number;
/*copy all(name,rollnum,mark..) data of next to current, disconect its next*/
list->next=list->next->next;
}
list=list->next;
}
}
23 回答
最好的方法仍然是将下一个节点的数据复制到要删除的节点中,将节点的下一个指针设置为下一个节点的下一个指针,然后删除下一个节点 .
指向要删除的节点的外部指针的问题虽然为真,但也适用于下一个节点 . 请考虑以下链接列表:
A-> B-> C-> D-> E-> F和G-> H-> I-> D-> E-> F
如果您必须删除节点C(在第一个链接列表中),通过上述方法,您将在将内容复制到节点C后删除节点D.这将产生以下列表:
A-> B-> D-> E-> F和G-> H-> I->悬空指针 .
如果您完全删除NODE C,结果列表将是:
A-> B-> D-> E-> F和G-> H-> I-> D-> E-> F.
但是,如果要删除节点D,并使用前面的方法,那么外部指针的问题仍然存在 .
最初的建议是改造:
a - > b - > c
至:
a - >,c
如果您保留信息,例如,从节点地址到下一个节点的地址,那么您可以在下次遍历列表时修复链 . 如果需要在下次遍历之前删除多个项目,则需要跟踪删除的顺序(即更改列表) .
标准解决方案是考虑其他数据结构,如跳过列表 .
也许做一个软删除? (即,在节点上设置“已删除”标志)如果需要,可以稍后清理列表 .
这绝对是一个测验,而不是一个真正的问题 . 但是,如果允许我们做出一些假设,可以在O(1)时间内解决 . 要做到这一点,列表指向的限制必须是可复制的 . 算法如下:
我们有一个列表如下:... - > Node(i-1) - > Node(i) - > Node(i 1) - > ...我们需要删除Node(i) .
将数据(非指针,数据本身)从节点(i 1)复制到节点(i),列表将如下所示:... - >节点(i-1) - >节点(i 1) - >节点(i 1) - > ...
将第二个节点(i 1)的NEXT复制到临时变量中 .
现在删除第二个节点(i 1),它不需要指向前一个节点的指针 .
伪代码:
麦克风 .
让我们假设一个结构列表
A - > B - > C - > D.
如果你只有一个指向B的指针并希望删除它,你可以做类似的事情
然后列表看起来像
A - > B - > D.
但是B会保留C的旧内容,有效地删除B中的内容 . 如果其他一段代码持有指向C的指针,这将无效 . 如果你试图删除节点D,它也行不通 . 如果你想进行这种操作,你需要使用一个没有真正使用的虚尾节点来构建列表,这样你就可以保证没有有用的节点会有一个NULL的下一个指针 . 对于存储在节点中的数据量很小的列表,这也更有效 . 像一个结构
没关系,但是就是这样
会有点累赘 .
不可能 .
有些黑客可以模仿删除 .
但是,实际上没有一个会删除指针所指向的节点 .
如果您有 external pointers 指向列表中的节点,则删除 following 节点并将其内容复制到要删除的 actual 节点的流行解决方案会产生副作用,在这种情况下,指向以下节点的外部指针将变为悬空 .
一种方法是为数据插入null . 每当遍历列表时,都会跟踪前一个节点 . 如果找到空数据,则修复列表,然后转到下一个节点 .
我很欣赏这个解决方案的独创性(删除下一个节点),但它没有回答问题的问题 . 如果这是实际的解决方案,那么正确的问题应该是“从链接列表中删除指定给定指针的节点中包含的VALUE” . 但是,当然,正确的问题可以为您提供解决方案的提示 . 制定这个问题的目的是让人感到困惑(实际上这件事发生在我身上,特别是因为面试官甚至没有提到节点位于中间) .
不是,如果你想保持列表的可穿越性 . 您需要更新上一个节点以链接到下一个节点 .
无论如何,你怎么会在这种情况下结束?你想做什么让你问这个问题?
您必须沿着列表前进才能找到上一个节点 . 这将使删除一般为O(n ** 2) . 如果您是唯一进行删除的代码,您可以通过缓存上一个节点并在那里开始搜索来做得更好,但这是否有帮助取决于删除的模式 .
特定
A - > B - > C - > D.
和一个指向项目B的指针,你会删除它
1.释放属于B成员的任何记忆
2.将C的内容复制到B(这包括它的"next"指针)
3.删除整个项目C.
当然,您必须小心边缘情况,例如处理一个项目的列表 .
现在有B的地方,你有C并且以前存储的C被释放了 .
是的,但你不能脱钩 . 如果你不关心腐败记忆,请继续;-)
是的,但删除后列表将被破坏 .
在这种特定情况下,再次遍历列表并获取指针!一般来说,如果你问这个问题,可能存在你正在做的事情的错误 .
为了到达上一个列表项,您需要从头开始遍历列表,直到找到带有指向当前项的
next
指针的条目 . 然后你必须修改以从列表中删除当前项 - 只需将previous->next
设置为current->next
然后删除current
.编辑:Kimbo不到一分钟就打败了我!
您可以使用标志将节点设置为脱离列表,然后在下一次正确的遍历中删除它们,从而延迟脱钩 . 设置为脱链的节点需要由爬网列表的代码正确处理 .
我想您也可以从头开始再次遍历列表,直到找到指向列表中项目的内容 . 几乎没有最佳,但至少比延迟脱钩更好的想法 .
一般来说,你应该知道你刚刚来自的项目的指针,你应该传递它 .
(编辑:Ick,我花了很多时间来输出一个完整的答案,三千万人几乎涵盖了我要提到的所有要点 . :()
唯一明智的方法是使用几个指针遍历列表,直到前导者找到要删除的节点,然后使用尾随指针更新下一个字段 .
如果要有效地从列表中删除随机项,则需要进行双重链接 . 如果您想从列表的头部获取项目并在尾部添加它们,则不需要双重链接整个列表 . 单独链接列表,但使列表中最后一项的下一个字段指向列表中的第一个项目 . 然后将列表“head”指向尾部项目(而不是头部) . 然后很容易添加到列表的尾部或从头部删除 .
你有名单的负责人,对吧?你只是遍历它 .
假设您的列表由“head”指向,并且节点将其删除为“del” .
C风格的伪代码(点数在C中为 - >):
下面的代码将创建一个LL,n然后要求用户给出要删除的节点的指针 . 它将在删除后打印列表它通过在要删除的节点之后复制节点,在要删除的节点上执行相同的操作,然后删除要删除的节点的下一个节点 . 即
A B C D
将c复制到b并释放c,以便得到结果
A-C-d
如果你有一个链表A - > B - > C - > D和一个指向节点B的指针 . 如果你必须删除这个节点你可以将节点C的内容复制到B,节点D复制到C并删除D.但是我们不能在单链表的情况下删除节点,因为如果我们这样做,节点A也将丢失 . 虽然我们可以在双链表的情况下回溯到A.
我对吗?
这是我放在一起执行OP所要求的代码的一段代码,甚至可以删除列表中的最后一个元素(不是以最优雅的方式,但它完成了它) . 在学习如何使用链表时写了一遍 . 希望能帮助到你 .