Swift 数据结构学习:栈与队列

本篇文章主要内容: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)
    }
}
复制代码
相关文章
相关标签/搜索