首页 > 解决方案 > 删除 Swift 链表中的元素

问题描述

对于节点类

public class ListNode: CustomStringConvertible {
    public var description: String {
        return val.description + (next?.description ?? "")
    }
         public var val: Int
         public var next: ListNode?
         public init(_ val: Int) {
                 self.val = val
                     self.next = nil
             }
     }

有一个头和节点,这样

let head = ListNode(4)
let second = ListNode(5)
let third = ListNode(1)
let forth = ListNode(8)
head.next = second
second.next = third
third.next = forth
forth.next = nil

我们可以简单地删除第二个节点

head.next = third

会释放第二个内存并释放内存吗?

或者我们是否需要从第二个中删除参考,这样

second.next = nil

标签: swift

解决方案


要实际观察去初始化,我们可以添加一个deinitListNode

deinit {
    print("\(val) deinit")
}

您当前的代码不会导致任何内容被取消初始化,因为请记住,对象只有在没有其他对象持有对它的引用时才会被取消初始化。在您当前的代码中,全局范围仍然具有保存对第二个节点的引用的let常量second,即使在head.next = third执行之后也是如此。这会导致第二个节点不会被取消初始化。

那么,使第二个节点取消初始化的一种方法是删除let除 之外的所有常量head

let head = ListNode(4)
head.next = ListNode(5) // second
head.next?.next = ListNode(1) // third
head.next?.next?.next = ListNode(8) // fourth

然后删除第二个节点:

head.next = head.next?.next

这会导致打印以下内容:

5 deinit

表示第二个节点被取消初始化。

此处设置second.next为 nil 无关紧要,因为它second.next包含对第三个节点的引用。将其设置为 nil 只会减少指向第三个节点的引用数量,从而努力取消初始化第三个节点。


推荐阅读