【发布时间】:2021-06-09 03:30:49
【问题描述】:
假设我有一个单链表,我正在遍历它并调用某个函数 f() 在某些条件下删除某些元素。该函数可以删除同一个列表中的多个元素,这会使我们正在遍历的指针无效....
处理这种情况的最佳方法是什么..
【问题讨论】:
-
两个指针一起使用,一个用于删除,另一个用于相邻元素的地址
标签: pointers data-structures linked-list singly-linked-list
假设我有一个单链表,我正在遍历它并调用某个函数 f() 在某些条件下删除某些元素。该函数可以删除同一个列表中的多个元素,这会使我们正在遍历的指针无效....
处理这种情况的最佳方法是什么..
【问题讨论】:
标签: pointers data-structures linked-list singly-linked-list
确实,当您删除单链表中的一个节点时,一旦您释放相应的内存,您对该已删除节点的引用(指针)就会失效。
附带说明:在某些编程语言中,这从来都不是问题,因为它们会为您进行内存管理,因此无法引用已释放的内存(例如 Java)。在这些环境中,当(或之后)不再引用内存时,内存就会被释放。
在列表遍历期间处理此问题的一般方法是在列表中保留对 next 节点的引用。为了删除当前节点,您还需要重新连接在前一个节点中引用它的指针。所以你需要三个引用:previous、current 和 next。
伪代码:
prevptr := NIL
currentptr := headptr
while currentptr != NIL:
nextptr := currentptr->next
if decision_to_delete(currentptr):
if prevptr != NIL:
prevptr->next := nextptr
else:
headptr := nextptr
dispose_memory(currentptr->)
else:
prevptr := currentptr
currentptr := nextptr
如果你有一个函数 f() 可能会删除几个 连续 节点,从你传递它的当前节点开始,然后确保函数 返回 一个对它没有删除的第一个节点:
prevptr := NIL
currentptr := headptr
while currentptr != NIL:
currentptr := f(currentptr)
if prevptr != NIL:
prevptr->next := currentptr
else:
headptr := currentptr
if currentptr == NIL:
return
prevptr := currentptr
currentptr := currentptr->next
在这种情况下,f 负责决定是否删除节点(如果有)并处理被删除的节点占用的内存。 f 的实现将使用 nextptr 工作方式,因此我们不再需要在调用代码中单独引用。
【讨论】: