本篇文章主要内容:
- 栈与队列的基本概念
- 栈与队列的基本结构
- 栈与队列的互相实现
栈
概念
结构
对栈来说,一般我们只需要关注:push, pop, isEmpty, peek, size 等操作。
顺序存储结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Stack { // 是否为空 var isEmpty: Bool { return stack.isEmpty } // 栈的大小 var size: Int { return stack.count } // 栈顶元素 var peek: Int? { return stack.last } // 入栈 func push(_ value: Int) { stack.append(value) } // 出栈 func pop() -> Int? { return stack.popLast() } private var stack: [Int] = [] }
|
链式存储结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| class Node { var value: Int? var next: Node? init(_ value: Int?) { self.value = value self.next = nil } }
class Stack_Link { private var head: Node? // 指向栈顶元素的指针 var isEmpty: Bool { return head == nil } var size: Int { get { var count = 0 var node = head?.next while node != nil { count += 1 node = node?.next } return count } } var peek: Node? { return head?.next } func push(_ value: Int) { if head == nil { head = Node(nil) } let newNode = Node(value) let lastTop = head?.next newNode.next = lastTop head?.next = newNode } func pop() -> Node? { let top = head?.next head?.next = top?.next return top } }
|
队列
概念
结构
对队列来说,一般我们只需要关注:enterQueue, outQueue, isEmpty, peek, size 等操作。
队列顺序存储结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Queue { // 是否为空 var isEmpty: Bool { return queue.isEmpty } // 队列的大小 var size: Int { return queue.count } // 队头元素 var peek: Int? { return queue.last } // 入队操作 func enterQueue(_ value: Int) { queue.append(value) } // 出队操作 func outQueue() -> Int? { if let element = queue.first { queue.removeFirst() return element } return nil } private var queue: [Int] = [] }
|
队列链式存储结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| class Node { var value: Int? var next: Node? init(_ value: Int?) { self.value = value self.next = nil } }
class Queue_Link { private var head: Node? // 指向队头 private var tail: Node? // 指向队尾 var isEmpty: Bool { return head == nil && tail == nil } var size: Int { get { var count = 0 var node = head?.next while node != nil { count += 1 node = node?.next } return count } } var peek: Node? { return head?.next } func enterQueue(_ value: Int) { let newNode = Node(value) if head == nil { head = Node(nil) tail = Node(nil) head?.next = newNode tail?.next = newNode } else { let lastTail = tail?.next lastTail?.next = newNode tail?.next = newNode } } func outQueue() -> Node? { let top = head?.next head?.next = top?.next return top } }
|
互相实现
用栈实现队列
思路:因为栈的先进后出特性,需要完成先进先出的特点。我们需要用到两个栈,一个 enterStack,专门负责入队的操作,另一个 outStack,负责协助出队。当入队时,我们将新元素 push 到 enterStack 中,出队时分为两个步骤,先将 enterQueue 的元素 pop 出来,并将 pop 的元素加入到 outStack 中,此时 outStack 的栈顶元素就是最先入队的元素。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class ImplementQueueByStack { private var enterStack = Stack() private var outStack = Stack() var isEmpty: Bool { return enterStack.isEmpty && outStack.isEmpty } var size: Int { return enterStack.size + outStack.size } var peek: Int? { get { tab() return outStack.peek } } func enterQueue(_ value: Int) { enterStack.push(value) } func outQueue() -> Int? { tab() return outStack.pop() } // 将 enter 中的值,加入到 out 中 private func tab() { if outStack.isEmpty { while !enterStack.isEmpty { outStack.push(enterStack.pop()!) } } } }
|
用队列实现栈
思路:根据栈实现队列的思路,这里我们也用两个队列来实现栈。一个 enterQueue,负责入栈,另一个 outQueue 负责协助出栈。入栈时,将新的元素加入到 enterQueue中,出栈时,也分为两个步骤,先将 enterQueue 中的元素出队至最后一个元素,并将所有出队的元素加入到 outQueue 中,此时,enterQueue 中剩下的元素即是我们需要出栈的元素。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| class ImplementStackByQueue { private var enterQueue = Queue() private var tempQueue = Queue() var isEmpty: Bool { return enterQueue.isEmpty && tempQueue.isEmpty }
var size: Int { return enterQueue.size }
var peek: Int? { get { tab() let peekElement = enterQueue.peek tempQueue.enterQueue(enterQueue.outQueue()!) swap() return peekElement } } func push(_ value: Int) { enterQueue.enterQueue(value) } func pop() -> Int? { tab() let popElement = enterQueue.outQueue() swap() return popElement } private func tab() { while enterQueue.size != 1 { tempQueue.enterQueue(enterQueue.outQueue()!) } } private func swap() { (enterQueue, tempQueue) = (tempQueue, enterQueue) } }
|