我正在尝试对列表实现delete()方法(无HEAD ref)
我发现可以将参数修改为结构。
func (l *LinkedList) Delete(n *Node) {
if n.next == nil {
n = nil
} else {
current := &n
*n = *n.next
*current = nil
}
}
“其他”部分工作正常,但是删除最后一个节点不会修改列表
尝试使用
*n = nil
但是然后我有编译错误。
不能在分配中使用nil作为Node类型
在此游乐场中完成的代码:
你只是做错了。我的意思是从单个链接列表中删除经典元素。正确的方法:
func (l *LinkedList) Delete(n *Node) {
// if we want to delete the head element - just move the head pointer
if l.head == n {
l.head = n.next
return
}
// otherwise find previous element to the one we are deleting
current := l.head
for current != nil && current.next != n {
current = current.next
}
// and move that previous element next pointer to the next element
if current != nil {
current.next = n.next
}
}
https://play.golang.org/p/_NlJw_fPWQD
那么,您的示例出了什么问题?在删除功能中,您将收到指向某个节点的指针。该指针是函数的局部变量,就像局部变量一样。您是否将nil分配给函数内部的局部变量都没有关系。在外面-没有人会看到这样的作业。您要做的是-更改上一个列表项的下一个指针。这样,该项目将不再位于列表中。GC将删除实际分配的内存。
更新:
由于go指针是“真实的”指针,因此可以使用Linus在其著名的TED演讲中(以及在slashdot问答中较早的版本中建议的),通过使用附加级别的间接实现,而无需特殊的头部去除情况(请参见“最喜欢的hack”)题):
func (l *LinkedList) Delete(n *Node) {
// initialize indirect with the address of a head pointer
indirect := &(l.head)
// until indirect has address of a pointer to the node we're deleting
for *indirect != n {
// check that it's not the end of the list
if (*indirect).next == nil {
// the node we're tryign to delete is not in the list
return
}
// set indirect to the address of the next pointer
indirect = &(*indirect).next
}
// indirect has address of a pointer we need to modify to delete the node
*indirect = n.next
}
https://play.golang.org/p/hDy3hB5LUME
与删除head元素的简单特殊情况相比,IMO的两个层次的理解更难理解,但是Linus并不是像我这样的普通开发人员:)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句