我决定改进我对数据结构的了解,并且遇到了链表。
我想知道是否有人在移动开发或使用swift作为他们的语言的任何其他类型的项目中使用它们的任何实际示例,因为对我来说似乎Array类已经具有足够的灵活性,因为它是
答案 0 :(得分:3)
您应该在需要主要利益的时候使用链接列表:O(1)在列表中的任意点插入和删除。
大多数人使用链表制作的错误是试图将它们作为Swift中的值类型实现。这非常困难,结果数据结构通常是无用的。最常见的形式是enum:
enum List<T> {
indirect case Cons(T, List<T>)
case Nil
}
let list = List.Cons(1, .Cons(2, .Cons(3, .Nil)))
我从未见过有人提出过有效的实施方案。 Swift中的高效集合需要copy-on-write,而且很难为枚举构建。
在Swift中构建链表的自然方式是作为可变引用类型。这很容易提高效率,非常有用。
class List<T> {
var value: T
var next: List<T>?
init(_ value: T, _ next: List<T>?) {
self.value = value
self.next = next
}
}
let list = List(1, List(2, List(3, nil)))
在这种形式下,只要你想在列表中的任意点插入和删除O(1),就可以使用它。
如果您有几个共享重要尾部的大型列表,您也可以将其构建为不可变引用类型(使用let
)。我从来没有见过这种做法。
我知道大多数沿着这条路走下去的人都想要一个不可变的链表,这样他们就可以实现许多非常漂亮的递归算法,这些算法建立在它们之上,并且在FP语言中非常常见(这可能更多地说明了我认识的人)而不是问题本身)。但斯威夫特充其量只是对递归有点敌视,所以除了作为一项运动之外,这很难让IMO感到麻烦。但递归算法只是链表的一种用法。作为O(1)任意插入数据结构,它们在Swift中与在Pascal和C中一样有用,并且您以大致相同的方式构建它们。