给定链表节点的以下定义:
class ListNode {
var value: Int = 0
var node: ListNode? = nil
static var root:ListNode? = nil
init() {
}
init(value:Int) {
self.value = value
}
然后,插入函数的以下实现将起作用:
if (ListNode.root == nil) {
ListNode.root = ListNode(value: value)
}
else {
var temp = ListNode.root
while (temp!.node != nil) {
temp = temp!.node
}
temp!.node = ListNode(value: value)
}
然而,相同功能的这种实现不起作用:
var temp = ListNode.root
while temp != nil {
temp = temp!.node
}
temp = ListNode(value: value)
为什么后者不起作用,如何重新编写(以简洁的形式,不使用递归)? 如果问题是因为temp是副本而不是引用,那么如何将其转换为引用呢?
(它不起作用,因为插入后ListNode.root保持不变)
答案 0 :(得分:0)
ListNode.root在后一种情况下保持不变,因为它没有在任何地方分配任何内容。
我会按如下方式实现:
class ListNode {
static var root: ListNode? = nil
static var tail: ListNode? = nil
var nextNode: ListNode? = nil
var value: Int = 0
init() { }
init(value: Int) {
self.value = value
}
static func insert(value: Int) {
switch tail {
case nil:
ListNode.root = ListNode(value: value)
ListNode.tail = ListNode.root
default:
let newTail = ListNode(value: value)
ListNode.tail?.nextNode = newTail
ListNode.tail = newTail
}
}
}
<强> [UPD] 强>
在swift中有两种类型的属性/变量,即值和对象。
当value属性(例如Int
或某些struct
)被分配给(临时)变量时,它正被复制。并且新变量与原始变量不同,也就是说,任何一个变量都不会自动反映在另一个变量中。
现在,对象有点不同。它们本质上是按值复制的指针。即如果您有两个引用 对象的变量,则更改<其中一个的em> property 将被&#34;看到&#34;由另一个(因为两者的指针指向相同的内存区域)。但如果两者都是零,那么没有什么可分享的。
此外,如果您为varA
分配新对象,那么这将使varB
指向同一个旧对象。即以下内容:
let varA = SomeObject()
let varB = varA
lat varA = SomeObject()
...最终会有varA
和varB
持有对不同对象的引用。
答案 1 :(得分:0)
在第二种情况下,您将新节点分配给temp
,但之后您不会将温度分配回ListNode
结构。
这一行
var temp = ListNode.root
说,创建一个新变量temp
,它是对ListNode
的引用,并在ListNode.root
中包含相同的引用。由于ListNode.root
最初为nil
,因此temp
也将保持为零。 temp
只是堆栈中的一些空间,因此当您为其分配新的对象引用时,它不会更新ListNode.root
。您需要使用&amp;参考ListNode.root
。为了工作,但以这种方式使用指针更多&#34; C&#34;而不是&#34;斯威夫特&#34;而不是你会做什么。在Swift中&
仅用于函数的inOut
参数。
在Swift中,你可以做得比你已经做得好得多(除非你引入了其他答案中建议的尾部引用)。
可以说,最好是可以阅读&#34;代码比&#34;聪明&#34;代码无论如何。
此外,使用静态类root
限制了类的实用程序,因为您只能拥有一个列表
我会使用两个班级。一个列表,然后是ListNode
-
List
Class List {
var root: ListNode? = nil
func insert(value:Int) {
var newNode=ListNode(value: value)
if (self.root == nil) {
self.root=newNode
}
else {
var destinationNode=self.root!
while (destinationNode.node != nil) {
destinationNode=destinationNode.node!;
}
destinationNode.node=newNode
}
}
}
class ListNode {
var value: Int = 0
var node: ListNode? = nil
init(value:Int) {
self.value = value
}
}