栈和队列的小小世界

179 阅读2分钟

「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战

前端能够用得到的数据存储结构之二:栈 + 队列

  • LIFO 先进后出
  • 线性序列
  • 栈顶 —— 可以进行进出操作的一端
  • 栈底 —— 不能进行进出操作的一端
  • 顺序存储 + 链式存储

顺序栈

  • 两个指针:【 栈底:base + 栈顶:top 】
  • 数据结构定义
    • 动态分配(需要预先分配空间)
    • 静态分配(定长数组)
  • 按顺序存储
  • 基本操作:【 初始化 + 入栈 + 出栈 + 取栈顶元素 】
    • 初始化(预分配空间 maxSize + 栈顶指针 top + 栈底指针 base)
    • 入栈(验满 -> top++)
    • 出栈(验空 -> top-- 栈顶元素暂存到变量)
    • 取栈顶元素(栈顶元素复制 -> top 不变 + size 不变)
  • 劣势:预分配空间 —— 空间浪费 + 溢出
  • 倾向:元素个数变化不大

链栈

  • 节点地址不连续 + 一个栈顶指针
  • 节点(数据域 + 指针域)
  • 操作(只能在头部进行)
  • 基本操作:【 初始化 + 入栈 + 出栈 + 取栈顶元素 】
    • 初始化(栈顶指针为空 s = null)
    • 入栈(创建新节点 -> 节点数据域添加元素 -> 栈顶指针指向新元素)
    • 出栈(栈顶指针指向下个节点 -> 释放空间)
    • 取栈顶元素(栈顶元素复制 -> 栈顶指针不变)
  • 劣势:每个节点一个指针域 —— 结构性开销比较大
  • 倾向:元素个数变化较大

队列

  • FIFO 先进先出
  • 队头 front —— 出元素的一端
  • 队尾 rear —— 进元素的一端

顺序队列

  • 连续的存储空间
  • 两个指针 —— 整型变量 【 front + rear 】:记录队头队尾下表
  • 预分配空间
  • 基本操作
    • 空队(front = rear)
    • 入队(rear++ 队尾后移)
    • 出队(front++ 队头后移)
    • 队满(front = rear)

循环队列

  • 队满判定条件 【 (rear + 1)%Maxsize = front 】
  • 基本操作
    • 初始化(front = rear = 0)
    • 入队(验满 rear++)
    • 出队(验空 变量暂存队头 -> front++)
    • 队列长度 【(rear - front + Maxsize)% Maxsize 】

链队列

  • 只在队头删除 + 只在队尾插入
  • 基本操作
    • 初始化(头节点 + front + rear -> 头尾指针指向头节点)
    • 入队(新节点 -> 元素存入节点数值域 -> 新节点插入队尾 + 尾指针后移)
    • 出队(front ->next = p->next 跳过被删除的节点p)
    • 取队头元素(front->next->data)