本篇文章主要内容:node
栈(stack)是限定仅在表尾进行插入和删除操做的线性表。bash
咱们把容许插入和删除的一端称为栈顶(top),另外一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(LastIn First Out)的线性表,简称LIFO结构。app
对栈来讲,通常咱们只须要关注:push, pop, isEmpty, peek, size 等操做。ui
顺序存储结构:spa
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] = []
}
复制代码
链式存储结构:指针
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
}
}
复制代码
队列(queue)是只容许在一端进行插入操做,而在另外一端进行删除操做的线性表。code
队列是一种先进先出(First In First Out)的线性表,简称FIFO。容许插入的一端称为队尾,容许删除的一端称为队头。队列
对队列来讲,通常咱们只须要关注:enterQueue, outQueue, isEmpty, peek, size 等操做。element
队列顺序存储结构:rem
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] = []
}
复制代码
队列链式存储结构:
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 的栈顶元素就是最早入队的元素。
代码:
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 中剩下的元素便是咱们须要出栈的元素。
代码:
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)
}
}
复制代码