在Swift中反向链接列表

时间:2019-01-05 10:36:51

标签: swift data-structures

在Swift中反转链表很容易。我有一个可行的解决方案。但是,在准备白板采访时,我快速制作的版本根本无法正常工作,而且我无法确定原因。

我需要知道以下原因为何不起作用-我认为是在Playground上

tail = previous

行错误和执行永远不会完成。

func reverseLL (node: Node?) -> Node? {
    guard node != nil else { return nil }
    var tail : Node? = node
    var previous = node?.next
    while previous != nil {
        let tailRef = previous?.next
        previous?.next = tail
        tail = previous
        previous = tailRef
    }
    return tail
    }

我对链表的定义是:

class Node: CustomStringConvertible {
    var data: Int
    var next: Node?

    var description: String {
        return String(data) + (next != nil ? next!.description : "")
    }

    init (data: Int) {
        self.data = data
        next = nil
    }

    func appendToTail(data: Int) {
        if (next != nil) {
            next?.appendToTail(data: data)
        }
        else {
            next = Node(data: data)
        }
    }
}

我的reverseLL的工作版本(我接受的版本更像是“ Swifty”)如下,但我认为它的功能应与我以前的定义相同。

 func reverseLL (node: Node?) -> Node? {
guard node != nil else { return nil }
        var tail: Node?
        var headNode = node
        while let head = headNode {
            let tailRef = head.next
            head.next = tail
            tail = head
            headNode = tailRef
        }
        return tail
    }

因此使用创建链接列表

let ll = Node(data: 3)
ll.appendToTail(data: 4)
ll.appendToTail(data: 4)
ll.appendToTail(data: 5)

按3445的顺序提供数据

并通过

反转
reverseLL(node: ll)

按5443的顺序提供数据

要清楚,为什么

tail = previous
在我对reverseLL的第一个定义中

行暂停执行?

2 个答案:

答案 0 :(得分:1)

第二个版本更快速,因为您正在使用可选绑定并避免了可怕的强制展开。

第一个版本中的问题是tail最初等于node。在您给出的示例中为( 3-> 4-> 4-> 5 )。

因此,当您在第一次迭代中执行previous?.next = tail时,previous变为( 4-> 4-> 5-> 3-> 4-> 5-> 3-> 4- > 5-> ... )。请注意,数据等于5的节点现在指向数据等于3的节点。这就造成了无限循环。


简化

后卫声明也可以写成:

guard node?.next != nil else {
    return node
}

其中将包含具有单个节点的列表。

答案 1 :(得分:0)

这里是完整的代码,包括类、函数和输入输出的东西

// 首先我们创建类来存储链表的数据

class Node {
    var data: Int
    var next: Node?

    var description: String {
        return String(data) + (next != nil ? next!.description : "")
    }

    init (data: Int) {
        self.data = data
        next = nil
    }

    func appendToLast(data: Int) {
        if (next != nil) {
            next?.appendToLast(data: data)
        } else {
            next = Node(data: data)
        }
    }
}

//返回反向链表的函数

func reverseLinkedList(node: Node?) -> Node? {
guard node != nil else { return nil }
        var tail: Node?
        var headNode = node
        while let head = headNode {
            let tailRef = head.next
            head.next = tail
            tail = head
            headNode = tailRef
        }
        return tail
    }

//输入链表中的所有数据,并在print函数中输出。

let ll = Node(data: 3)
ll.appendToLast(data: 4)
ll.appendToLast(data: 4)
ll.appendToLast(data: 5)
let reversedLL = reverseLinkedList(node: ll)
print(reversedLL?.description ?? "No Data")