使用选项的链接列表实现

时间:2015-07-06 21:40:12

标签: ios swift

给定链表节点的以下定义:

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保持不变)

2 个答案:

答案 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()

...最终会有varAvarB持有对不同对象的引用。

答案 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
    }   
}