大话数据结构 第四章 栈和队列

大话数据结构 第四章 栈和队列

  • 栈(FILO先进后出)
    • 定义
    • 顺序存储结构
    • 两栈共享空间
    • 链式存储结构(链栈)
      • 定义
      • 进栈
      • 出栈
    • 顺序栈和链式栈的比较
    • 栈的应用——递归
  • 队列(FIFO先进先出)
    • 定义
    • 循环队列(顺序结构)
      • 普通队列顺序存储的不足
      • 定义
    • 链队列(链式结构)
      • 定义
      • 入队操作
      • 出队操作
    • 循环队列和链队列的比较

栈(FILO先进后出)

定义

  • 栈是限定仅在表尾进行插入和删除的线性表
  • 把允许插入和删除的一段称为栈顶,另一端称为栈底
  • 进栈push,出栈pop

顺序存储结构

  • 空栈 top = -1
  • 进栈和出栈的时间复杂度都是O(1)

两栈共享空间

  • 思路是让两个栈的栈顶top指针在数组的两端,向中间靠拢
  • 栈满判定条件: top1 + 1 == top2;
  • 通常适用于相同数据类型、两个栈的空间需求相反时(你多我少,我多你少)

链式存储结构(链栈)

定义

  • 把栈顶放在单链表的头部,不需要头结点。

进栈

  • 假设元素e的新结点是s:把e赋值给s的数据域:s->data = e;
  • 把当前的栈顶元素赋值给新结点的直接后继,即:s->next = s-> top;
  • 将新的结点s赋值给栈顶指针: s->top = s;
  • 时间复杂度为O(1)

出栈

  • 假设p用来存储要删除的栈顶节点,将栈顶结点赋值给p:p = s->top;
  • 使得栈顶指针下移一位,指向后一结点:s->top = s->top->next;
  • 释放结点p:free§;
  • 时间复杂度为O(1)

顺序栈和链式栈的比较

  • 顺序栈需要事先确定一个固定的长度,可能会存在空间浪费的问题,优势是存取时定位很方便;而链栈则要求每个元素都有指针域,这增加了内存开销
  • 元素变化不可预料时用链栈,变化在可控范围内则用顺序栈

栈的应用——递归

  • 递归函数:一个直接调用自己或通过一系列的调用语句间接地调用自己的函数
  • 每个递归定义都必须至少有一个条件,满足时递归不再进行,防止陷入永不结束的无穷递归中
  • 迭代使用的是循环结构,递归使用的是选择结构

队列(FIFO先进先出)

定义

  • 队列:只允许在一段进行插入操作,而在另一端进行删除操作的线性表

循环队列(顺序结构)

普通队列顺序存储的不足

  • 插入操作的时间复杂度为O(1),删除操作的复杂度为O(n)
  • 存在“假溢出”

定义

  • 循环队列:首尾相接的顺序存储结构的队列
  • 队列满的条件:(rear + 1)%(QueueSize)== front
  • 队列长度公式:(rear - front + QueueSize)

链队列(链式结构)

定义

  • 链队列就是线性表的单链表,只能尾进头出

入队操作

  • 入队操作时,其实就是在链表尾部插入结点
  • 设置新结点s,将元素数据e赋值给s:s->data = e;
  • 将s的后继指向NULL:s->next = NULL;
  • 把新结点s赋值给原队尾结点的后继(Q为队列):Q->rear->next = s;
  • 把当前的s设置为队尾的结点:Q->rear = s;

出队操作

  • 出队操作时,就是头结点的后继结点出队,将头结点的后继改为它后面的结点,若链表出头结点外只剩一个元素时,则需将rear指向头结点

循环队列和链队列的比较

  • 时间上,两种队列的基本操作都是O(1)
  • 空间上,循环队列是实现申请好空间,使用期间不释放空间,可能存在空间的浪费;链队列是实时申请和释放结点,存在一些时间开销
  • 总的来说,在可以确定队列长度最大值的情况下, 使用循环队列;无法预估长度时,使用链队列

你可能感兴趣的:(大话数据结构)