【数据结构与算法】之栈与队列的应用和操作

一、概念

  • 栈:限定仅在表尾进行插入和删除操作的线性表,允许插入和删除的一端为栈顶,另一端是栈底。
  • 性质:栈是一种LIFO(Last In First Out)的线性表,也就是数据元素遵循后进先出的原则。
  • 栈的抽象数据类型:
ADT 栈(Stack)
Data
      具有线性表一样的性质。
Operation
      top:获取栈顶元素
      count:栈的长度
      isEmpty:栈内元素是否为空
      push(data):元素进栈
      pop():元素出栈
      removeAll():清空栈内元素
EndADT
  • 栈的分类(存储结构):
    ① 栈的顺序存储结构:单栈、共享栈;
    ② 栈的链式存储结构;

  • 共享栈:两个顺序栈共享存储空间,栈1的栈顶在下标0处,栈2的栈顶在下标n-1处。

  • 栈的顺序结构和链式结构区别:
    ① 顺序结构需要预先估算存储空间大小,适合数据元素变化不大的情况;
    ② 链式结构不需要预先估算存储空间,适合数据元素变化较大的情况;

  • 栈和线性表的不同之处在于,栈只有进栈和出栈操作,并且遵循后进先出的规则,也就是说数据元素顺序进栈,逆序出栈。栈可以实现回退操作,递归和四则运算等。

二、栈的操作

  • s.push(item) // 在栈顶压入新元素
  • s.pop() // 删除栈顶元素但不返回其值
  • s.empty() // 如果栈为空返回true,否则返回false
  • s.size() // 返回栈中元素的个数
  • s.top() // 返回栈顶的元素,但不删除该元素

三、栈的链式结构实现

public struct Stack<T> {
    private var stackData: [T] = []
    
    public var count: Int {
        return stackData.count
    }
    
    public var top: T? {
        if isEmpty {
            return nil
        } else {
            return stackData.last
        }
    }
    
    public var isEmpty: Bool {
        return stackData.isEmpty
    }
    
    public mutating func push(data: T) {
        stackData.append(data)
    }
    
    public mutating func pop() -> T? {
        if isEmpty {
            return nil
        } else {
            return stackData.removeLast()
        }
    }
    
    public mutating func removeAll() {
        stackData.removeAll()
    }
    
    public func printAllData() {
        for item in stackData {
            print(item)
        }
    }
}

队列

一、概念

  • 只允许在一段进行插入操作,而在另一端进行删除操作的线性表;
  • 性质:先进先出
  • 队列的抽象数据类型:
ADT 队列(Queue)
Data
    具有线性表一样的性质。
Operation
    front:队列第一个数据
    count:队列的长度
    isEmpty():队列是否为空
    enQueue(data):数据进队列
    deQueue():数据出队列
    removeAll():清空队列内的所有数据
EndADT
  • 顺序队列:就是使用数组来模拟队列,但是数组的插入和删除需要移动数据,比较繁琐。
  • 循环顺序队列:在顺序队列的基础上改造,使队列的队头和队尾可以在数组中循环变化,在数据插入和删除就不需要频繁移动数据了。但是顺序队列,都需要提前申请存储空间,还有溢出的可能。
  • 链式队列:为了解决顺序队列的不足,引用链式队列。不需要提前申请空间,只不过会引入频繁申请和释放的操作。
  • 队列有什么作用?在开发过程中,接触最多的应该是全局并发队列。为什么要用队列实现呢?在线程的优先级一样的情况下,不应该先申请系统资源的先被满足吗?这和在银行排队取钱是一个道理。

二、队列的操作

  • push(item)
  • q.pop()
  • q.front()
  • q.back()
  • q.size()
  • q.empty()

三、队列的链式结构实现

public struct Queue<T> {
    private var queueData: [T] = []
    
    public var front: T? {
        return queueData.first
    }
    
    public var isEmpty: Bool {
        return queueData.isEmpty
    }
    
    public var count: Int {
        return queueData.count
    }
    
    public mutating func enQueue(_ data: T) {
        queueData.append(data)
    }
    
    public mutating func deQueue() -> T? {
        if isEmpty {
            return nil
        } else {
            return queueData.removeFirst()
        }
    }
    
    public mutating func removeAll() {
        queueData.removeAll()
    }
    
    public func printAllData() {
        for value in queueData {
            print(value)
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Forever_wj/article/details/107502188