数据结构——栈与队列


欢迎大家访问我的个人博客:endeavorchuan.com

是一种仅限定在表尾进行插入或删除操作的线性表。

表尾→栈顶 表头→栈底 不含元素为空栈

栈为 LIFO 结构线性表(后进先出)。

基本操作

  • InitStack(&S): 构造一个空栈
  • DestroyStack(&S): 若栈S已存在,则将其销毁
  • ClearStack(&S): 若栈S已存在,则将S清为空栈
  • StackEmpty(S): 若S为空栈,返回TRUE,否则返回FALSE
  • StackLength(S): 返回栈S的元素个数,即栈的长度
  • GetTop(S, &e): 若栈S存在且非空,用e返回S的栈顶元素
  • Push(&S, e): 若栈S存在,插入元素e为新的栈顶元素
  • Pop(&S, &e): 若栈S存在且非空,删除S的栈顶元素,并用e返回其值
  • StackTraverse(S, visit()): 从栈底到栈顶依次对S的每个数据元素调用visit()

栈的实现

初始化空栈时,不应限定栈的最大容量。先为栈分配一个基本容量,然后在应用过程中,当栈空间不够使用时再逐段扩大。

存储空间初始分配量:STACK_INIT_SIZE 存储空间分配增量:STACKINCREMENT

typedef struct{
   SElemType  * base;           //base为栈底指针,始终指向栈底,base为NULL时,表明栈不存在
   SElemType  * top;           //top为栈顶指针,初值指向栈底,即top=base时,可判断为栈空
   int  stacksize;           //stacksize指示栈当前可使用的最大容量
}SqStack;

第一次存储分配为STACK_INIT_SIZE,存储空间不足时,继续分配STACKINCREMENT。

对于n个不同元素进栈,出栈序列的个数为(2n)!➗(n+1)➗(n!+n!)。

共享栈

可让两个顺序栈共享一个一维数据空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。
在这里插入图片描述
两个栈的栈顶指针都指向栈顶元素,top0=-1时0号栈空,top1=MaxSize时1号栈空。

两栈顶指针相邻,即top1-top0=1时,表示栈满。

0号栈进栈:top0先加1再赋值 1号栈进栈:top1先减1再赋值

可更有效的利用存储空间,两个栈空间相互调节,只有当存储空间占满时才会发生上溢。

栈的链式存储

链栈便于多个栈共享存储空间和提高效率,不存在栈满上溢的情况。

采用单链表实现,规定所有操作在单链表的表头进行。

链栈的操作与链表类似。

队列

只允许在表的一端进行插入,而在另一端删除的线性表。

队尾→允许插入的一端 队头→允许删除的一端

队列为 FIFO 结构的线性表(先进先出)。

基本操作

  • InitQueue(&Q): 构造一个空队列
  • DestroyQueue(&Q): 若队列Q存在,则将其销毁
  • ClearQueue(&Q): 若队列Q存在,将Q清空
  • QueueEmpty(Q): 若队列Q为空队列,则返回TRUE,否则返回FALSE
  • QueueLength(Q): 返回队列Q的元素个数,即队列的长度
  • GetHead(Q, &e): 若Q为非空队列,用e返回Q的队头元素
  • EnQueue(&Q, e): 插入元素e为Q的新的队尾元素
  • DeQueue(&Q, &e): 删除Q的队头元素,并用e返回其值
  • QueueTraverse(Q, visit()): 从队头到队尾,依次对Q的每个数据元素调用函数visit()

队列是操作受限的线性表,不可以随意读取队列中间的某个数据。

队列的顺序存储

front指示队头元素,rear指示队尾元素。

#define  MaxSize  50                   //定义队列中元素的最大个数
typedef  struct{
   ElemType  data[MaxSize];                   //存放队列元素
   int front,rear;                   //定义队头指针和队尾指针
}SqQueue;

队空时条件为:Q.fron == Q.rear == 0

进队操作:队不满时,先送值到队尾元素,再将队尾指针加1。

出队操作:队非空时,先取队头元素值,再将队头指针加1。

循环队列

将顺序队列打造成一个环状的空间,即把存储队列元素的表从逻辑上视为一个环。

  • 每删除一个队头元素,将front顺时针移动一个位置
  • 每插入一个元素,rear将顺时针移动一个位置
  • count存放队列中的元素个数,当count=size时,说明队列已满;count=0时,队列为空

在这里插入图片描述
循环队列解决了运算效率与空间利用率之间的矛盾。

链式队列

可看做是一个同时带有队头指针与队尾指针的单链表。

头指针指向队头结点,尾指针指向队尾结点。
在这里插入图片描述
当 Q.front == NULL && Q.rear == NULL 时,链式队列为空。

可将链式队列设计成带头结点的单链表,以便统一插入和删除操作。

适用于元素变动较大的情形,不存在队列满或溢出的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个昵称被占用的川川

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值