【发布时间】:2021-12-27 05:43:02
【问题描述】:
以下是链表实现的一部分,我对语义感到困惑:
class Node<T> {
var value: T
var next: Node?
weak var previous: Node?
init(value: T) {
self.value = value
}
}
struct LinkedList<T> {
var head: Node<T>?
var tail: Node<T>?
init() { }
// what this method actually does is unimportant, but it creates a linked list from a sequence
func createChain<S>(of sequence: S) -> (head: Node<T>, tail: Node<T>)? where S: Sequence, S.Element == T {
var iterator = sequence.makeIterator()
guard let firstValue = iterator.next() else {
return nil
}
var head: Node<T>
var tail: Node<T>
var currentNode = Node(value: firstValue)
head = currentNode
while let nextValue = iterator.next() {
let newNode = Node(value: nextValue)
currentNode.next = newNode
newNode.previous = currentNode
currentNode = newNode // ?
}
tail = currentNode
return (head: head, tail: tail)
}
}
假设我要使用上面的代码创建一个链表:
let linkedList = LinkedList<Int>()
let sequence = [0, 1, 2]
let chain = linkedList.createChain(of: sequence)
在while 循环的第一个循环中,快照如下:
while let nextValue = iterator.next() {
let newNode = Node(value: nextValue) // newNode: previous = nil, next = nil, value = 1
currentNode.next = newNode // currentNode: previous = nil, next = newNode, value = 0
newNode.previous = currentNode // newNode: previous = currentNode, next = nil, value = 1
currentNode = newNode // ?
}
当最后一行执行时,我表面上明白新节点必须不断替换当前节点才能循环遍历序列的所有元素,但我不确定当currentNode 设置@987654326 时会发生什么@。 newNode 覆盖 currentNode 是没有意义的,因为 currentNode 的 next 刚刚被分配了 newNode 和 newNode 的 next 为零。
如果newNode没有覆盖currentNode,newNode的内容如何不影响currentNode = newNode中的currentNode?
【问题讨论】:
-
只是将currentNode标记为当前列表的
tail,然后不断追加到tail。你可以认为变量名是一个指针,实际对象的内存在某处。在第一轮循环之后,newNode指针消失了,但它的内存仍然可以通过currentNode访问。 -
currentNode.next = newNode中的currentNode.next如何在currentNode = newNode之后发生时仍保持原样? -
因为Node是类,引用类型,所以当你分配新值时,它指向另一个地址。你应该多研究一下引用类型和值类型、指针和对象。
标签: ios swift data-structures linked-list