Swift Stack实现
在本教程中,我们将使用Swift讨论和实现数据结构:堆栈。
我们将看到Swift泛型如何使创建泛型堆栈变得容易。
Swift Stack
堆栈是一种数据结构,用于按特定顺序保存数据。
让我们看看它们的订购方式:
订单就像一堆书。
您可以继续在顶部的收藏夹中插入一本新书。
您只能删除或者查看最顶层的书。
这意味着要删除最底下的书,您必须删除上面的所有书。
此顺序称为后进先出(LIFO)。
下图展示了一个示例:
推入用于将元素插入堆栈。
Pop用于删除最上面的元素。
Peek用于查看最上方的元素。
默认情况下,如果堆栈为空,则返回nil。
我们可以使用数组,LinkedList等创建堆栈。
在本教程中,我们将使用数组。
堆栈的重要用例
在音乐播放列表应用程序中,歌曲在队列中排队并随机播放,通常您会意识到来回将下一首歌曲更改为新的随机歌曲。
这是通过堆栈发生的。
最新的歌曲被添加到堆栈的顶部。
如果您不喜欢那首歌,则可以随时按向后(pop)和前进(push)在队列中插入新的随机歌曲。
让我们启动XCode游乐场并实现Swift Stacks。
创建堆栈
我们可以通过以下方式在Swift中创建一个Stack:
struct Stack { private var myArray: [String] = [] }
我们定义了一个结构Stack,其中包含字符串数组。
让我们定义Swift结构中的push,pop和peek功能。
推
mutating func push(_ element: String) { myArray.append(element) }
此push函数将新元素附加到数组的LAST。
流行音乐
mutating func pop() -> String? { return myArray.popLast() }
这个pop函数使用Swift数组提供的popLast()函数删除LAST元素。
我们使用了可选的返回类型String,因为它可以返回nil。
窥视
func peek() -> String { guard let topElement = myArray.last else { print("This stack is empty.") } return topElement }
如果要显示自定义错误消息,而不是使用Optional,请使用Swift的guard let
语句。
这就是我们最终结构在XCode Playground中的外观。
struct Stack { private var myArray: [String] = [] mutating func push(_ element: String) { myArray.append(element) } mutating func pop() -> String? { return myArray.popLast() } func peek() -> String { guard let topElement = myArray.last else {return "This stack is empty."} return topElement } } var stack = Stack() stack.peek() stack.push("Swift Arrays") stack.push("Swift LinkedList") stack.push("Swift Stack") print(stack) stack.peek() stack.pop() stack.pop() stack.pop() stack.peek() stack.pop()
上面的堆栈只能容纳字符串。
此外,它不能很好地打印纸堆内容。
为此,我们可以使用CustomStringConvertible协议作为结构的扩展。
让我们为下面的Stack结构创建扩展:
extension Stack: CustomStringConvertible { var description: String { let header = "Swift Stack Begin\n" let bottomDivider = "\nSwift Stack End*\n" let elements = myArray.joined(separator: "\n") return header + elements + bottomDivider } }
以下是stack.description
的输出
它按推入的顺序打印堆栈。
我们需要使用reversed()方法将其反转:
let elements = myArray.reversed().joined(separator: "\n")
现在正确的堆叠顺序为:
Swift通用堆栈
让我们将上述Swift堆栈设为通用。
您只需要使用方括号中的通用参数更新堆栈定义!
struct Stack<T> { private var myArray: [T] = [] mutating func push(_ element: T) { myArray.append(element) } mutating func pop() -> T? { return myArray.popLast() } func peek() -> T? { return myArray.last } }
注意:在CustomStringConvertible协议中,我们使用joined
来连接元素。
这不适用于非字符串元素。
因此,我们需要先使用map运算符将元素映射到字符串,然后再进行连接。
let elements = myArray.reversed().map{ "\(##代码##)" }.joined(separator: "\n")
$0表示要映射的当前元素。