数据结构栈知识点梳理

一 栈的定义

栈(stack)是限定仅在表尾进行插入和删除操作的线性表

  • 不含任何元素的栈称为空栈

  • 允许插入和删除的一端成为栈顶(top),另一端称为栈底(bottom)

  • 具有LIFO(Last In First Out)结构

  • 栈元素具有线性关系,即前驱和后继,是特殊的线性表

二 栈的插入、删除
  • 栈的插入操作—进栈(push)

  • 栈的删除操作—出栈(pop)

三 栈的抽象数据类型
ADT 栈(stack)
Data同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系
OperationInitStack(&S):初始化操作,建立一个空栈SDestroyStack(*S):若栈存在,则销毁它ClearStack(*S):将栈清空StackEmpty(S):若栈为空,返回true,否则返回falseGetTop(S,*e):若栈存在且非空,用e返回S的栈顶元素Push(*S,e):若栈S存在,插入新元素e到栈S中并称为栈顶元素Pop(*S,*e):删除栈S中栈顶元素,并用e返回其值StackLength(S):返回栈S的元素个数
endADT
四 栈的顺序存储结构

栈只能在一头插入和删除,下标为0的一端作栈底比较好。定义一个top变量来指示栈顶元素在数组中的位置。

存储栈的长度StackSize,栈顶位置top必须小于StackSize。

当栈有一个元素时,top=0,所以空栈的判定条件为top=-1

出栈和入栈的时间复杂度都是O(1)

  • 栈的结构定义
typedef int SElemType;/*SElemType 类型根据实际情况而定,这里假设为int*/
typedef struct
{SElemType data[MAXSIZE];int top;/*栈顶指针*/
}SqStack;
  • 进栈操作

进栈push操作

Status Push(SqStack *S,SElemType e)
{if(S->top == MAXSIZE - 1)/*栈满*/{return ERROR;}S->top++;/*栈顶指针+1*/S->data[S->top] = e;/*将新插入元素赋值给栈顶空间*/return OK;
}
  • 出栈操作
Status Pop(SqStack *S,SElemType *e)
{if(S->top == -1)return ERROR;*e = S->data[S->top]; /*将要删除的栈顶元素赋值给e*/S->top--;return OK;
}
五 两栈共享空间

栈的顺序存储

优点:插入和删除操作不需要元素

缺点:需要提前确认存储空间,或者用编程手段扩容,空间利用率不高

解决方法:两栈共享空间,为了增加空间利用率,可以用一个数组来存储两个栈

如图:让一个栈的栈底为数组的始端(下标为0处),另一个栈为栈的末端(下标n-1处),两个栈的元素增加,向中间延伸

栈1为空,top1 == -1;栈2为空,top2 == n;栈满 top1+1 == top2

/*两栈共享空间结构*/
typedef struct
{SElemType data[MAXSIZE];int top1;int top2;
}SqDoubleStack;
  • 插入操作

增加一个StackNumber判断插入栈1还是栈2

/*插入元素e为新的栈顶元素*/
Status  Push(SqDoubleStack *S,SElemType e,int stackNumber)
{if(S->top1+1 == S->top2)return ERROR;if(stackNumber == 1)S->data[++S->top1]=e;else if(stackNumber == 2)S->data[--S->top2]=e;return OK;
}
  • 插入操作
/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR*/
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{if(stackNumber == 1){if(S->top1 == -1)return ERROR;*e = S->data[S->top1--];}else if(stackNumber == 2){if(S->top2 == MAXSIZE)return ERROR;*e = S->data[S->top2++];}        return OK;
}
六 栈的链式存储结构

链栈不需要头结点

基本不存在栈满的情况,除非内存没有空间

链栈空top == NULL

  • 链栈结构代码
typedef struct StackNode
{SElemType data;struct StackNode *next;
}StackNode,*LinkStackPtr;typedef struct LinkStack
{LinkStackPtr top;int count;
}LinkStack;
  • 进栈操作

/*插入元素e为新的栈顶元素*/
Status Push(LinkStack *S,SElemType e)
{LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));s->data=e;s->next=S->top; S->top=s;S->count++;return OK;
}
  • 出栈操作

Status Pop(LinkStack *S,SElemType *e)
{LinkStackPtr p;if(StackEmpty(*s))return ERROR;*e=S->top->data;p=S->top;S->top = S->top->next;free(p);S->count--;return OK;
}
七 总结

栈在使用过程中元素变化不可预料,有时很小,有时很大,那么最好用链栈。反之,大小在可控的范围内,用顺序栈。

栈更多的应用在递归

数据结构队知识点梳理

一 定义

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表

队列是一种先进先出(First In First Out)的线性表

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

二 队列的抽象数据结构
ADT 队列(Queue)
Data同线性表。元素具有相同的类型,相邻元素具有前驱和后继
OperationInitQueue(*Q):初始化操作,建立一个空队列QDestroyQueue(*Q):若队列Q存在,则销毁它ClearQueue(*Q):将队列清空QueueEmpty(Q):若队列为空,返回true,否则返回falseGetHead(Q,*e):若队列Q存在且非空,用e返回队列Q的队头元素EnQueue(*Q,e):若队列存在,插入新元素e到队列Q中并成为队尾元素DeQueue(*Q,*e):删除队列Q中的队头元素,并用e返回其值QueueLength(Q):返回队列Q中的元素个数
endADT
三 循环队列
  • 顺序存储结构存在不足容易发生数组越界的错误,假溢出现象。

  • 两个指针

    为了避免队尾和队头重合使处理十分麻烦,所以引入两个指针。front指针指向队头元素,rear指针指向队尾元素;front==rear时,指空队列

  • 循环队列定义

    头尾相接顺序存储结构称为循环队列。

  • 出现的问题

当front==rear的时候可能是队列为空,或可能是队列为满

解决办法:

  • 设置一个标志变量flag,当front == rear,且flag = 0时队列为空,当front == rear,且flag = 1时队列为满。
  • 当队列空时,条件就是front == rear,当队列为满的时候,修改其中的条件,保留一个元素空间,意思就是当队列满的时候,数组中还有一个空闲单元。

第二种解决方式不允许出现的情况

队满情况

四 循环队列一些列操作
  • 顺序存储结构代码

队列满的条件:
(rear+1)%QueueSize == front

通用的计算队列长度公式:
(rear-front+QueueSize)%QueueSize

typedef int QElemType;
/*循环队列的顺序存储结构*/
typedef struct
{QElemType data[MAXSIZE];int front;int rear;
}SqQueue;
  • 初始化循环队列
/*初始化一个空队列*/
Status InitQueue(SqQueue *Q)
{Q->front = 0;Q->rear = 0;return OK;
}
  • 循环队列求长度
/*返回Q的元素个数,也就是当前队列的长度*/
int QueueLength(SqQueue Q)
{return (Q.rear - Q.front + MAXSIZE)%MAXSIZE;
}
  • 循环队列的入队
/*若队列未满,则插入元素e为Q新的队尾元素*/
Status EnQueue(SqQueue *Q,QElemType e)
{if((Q->rear+1)%MAXSIZE == Q->front)return ERROR;Q->data[Q->rear] = e;Q->rear = (Q->rear+1)%MAXSIZE;return OK;
}
  • 循环队列的出队
/*若队列不空,则删除Q中队头元素,用e返回其值*/
Status DeQueue(SqQueue *Q,QElemType *e)
{if(Q->front == Q->rear)return ERROR;*e=Q->data[Q->front];Q->front = (Q->front+1)%MAXSIZE;return OK;
}

循环队列面临着数组溢出的问题,所以还需要不用担心队列长度的链式存储结构

五 队列的链式存储结构

理解:队列的存储结构,相当于线性表的单链表,只不过它只能尾进头出,简称链队列

队头指针指向链队的头结点,队尾指针指向终端结点。

  • 空队列,front和rear都指向头结点

  • 链队的存储结构
typedef int QElemType
typedef struct QNode /*结点结构*/
{QElemType data;struct QNode *next;
}QNode,*QueuePtr;
typedef struct /*队列的链表结构*/
{QueuePtr front rear;
}LinkQueue;
  • 入队操作

/*插入元素e为Q的新的队尾元素*/
Status EnQueue(LinkQueue *Q,QElemType e)
{QueuePtr s = (QueuePtr)malloc(sizeof(QNode));if(!s)exit(OVERFLOW);s->data = e;s->next = NULL;Q->rear->next = s;Q->rear = s;return OK;
}
  • 出队操作

/*若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR*/
Status DeQueue(LinkQueue *Q,QElemType *e)
{QueuePtr p;if(Q->front == Q->rear)return ERROR;p = Q->front->next;if(Q->rear == p)/*若队头是队尾*/Q->rear = Q->front;free(p);return OK;
}
六 循环队列和链队的比较

时间上:都是O(1),循环队列事先申请空间,使用不释放;链队申请和释放结点需要耗时。

空间上:循环队列需要固定长度,会造成空间浪费。链队不存在这些问题,更加的灵活多变。

数据结构栈(顺序栈、链栈、插入push、删除pop)、队(循环队,链队、入队push,出队pop)知识点梳理相关推荐

  1. 数据结构(C语言第二版)严蔚敏编,数据结构电子教材,线性表,栈,队列,顺序存储结构,初始化,入栈,出栈,入队,出队,c++

    前言 提示:本篇文章收录严蔚敏编写的数据结构C语言版本 简单介绍一下顺序表,顺序栈,循环队列,的顺序存储结构之间的区别 代码参考严蔚敏编写的<数据结构>,二维码动态演示可扫码可观看. - ...

  2. 判断出栈顺序是否正确(栈的压入、弹出序列)

    输入两个整数序列.其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序.为了简单起见,我们假设push序列的任意两个整数都是不相等的. 比如输入的push序列是1.2.3.4. ...

  3. 1-2、数据结构线性表之顺序表的基本操作插入、删除、遍历、初始化

    学习需要记录,更需要温习! 上一篇我们总结了什么是线性表,线性表的ADT类型,线性表的两种存储类型顺序存储结构和链式存储结构,今天正式进入线性表的顺序存储结构的总结和归纳,也就是数据结构的线性表的顺序 ...

  4. 《大话数据结构》Java实现 顺序存储的插入与删除

        欢迎大家关注我的公众号,有问题可以及时和我交流. 前言 <大话数据结构>这本书使用的是C语言编写,为了练习书上举的例子,使用Java按照作者的思想进行模拟出来. 也许我这里不是最好 ...

  5. Java数据结构与算法-SingleLinkedList单向链表插入,删除,查找,修改详解及代码

    SingleLinkedList单向链表插入,删除,查找,修改详解及代码 单向链表学习目标 1. 链表的介绍 2. 单向链表的存储特点以及原理 3. 基本操作:插入,删除等 4. 单向链表应用场景举例 ...

  6. java数据结构20:Big Bang(链表的插入、删除、遍历和查找)

    20:Big Bang(链表的插入.删除.遍历和查找) 总时间限制: 20000ms 内存限制: 131072kB 描述 学习累了的时候看看一集二十分钟左右的<生活大爆炸>也不失为一种乐趣 ...

  7. 重温数据结构:二叉排序树的查找、插入、删除

    读完本文你将了解到: 什么是二叉排序树 Binary Sort Tree, BST 二叉排序树的关键操作 1.查找 2.插入 3.删除 * 运行代码测试 一道面试题 总结 Thanks 我们知道,二分 ...

  8. 【数据结构入门】队列(Queue)详解(定义、销毁、入队、出队等)| 图解数据结构,超详细哦~

    文章目录 (1)前言 1)队列的概念 2)队列的结构 (2)队列的实现(链式结构) 1)队列的定义 2)队列的初始化 3)队列的销毁 4)入队(尾插) 5)出队(头删) 6)获取队列元素个数 7)获取 ...

  9. 队列的链式存储实现(简单的入队和出队操作)

    /************************************************************************ * * 文件名:2.2.5.cpp * * 文件描述 ...

  10. 链式队列的基本操作(入队、出队、遍历队列、清空队列)

    链式队列是一种特殊的链表,只能在尾部添加,在头部删除,类似于排队问题,先入先出 代码如下 #include<stdio.h> #include<malloc.h> #inclu ...

最新文章

  1. Future有返回值的线程
  2. c与python的区别-c语言和python的区别是什么
  3. Linux下载安装配置FTP
  4. 【工具】云文档办公利器!腾讯文档好评!
  5. Kafka Consumer端的一些解惑
  6. web元件库/常用web组件/常用表单/导航栏/边框/图标/日期时间选择器/评分组件/穿梭框/输入框/步骤条/计数器/输入框/Axure原型/axure元件库/rp原型/交互控件/五星评分器/导航框架
  7. SQL Server – QP的另一个X射线
  8. MD5加密 java实现
  9. Python使用matplotlib可视化模拟商场促销价格关系折线图
  10. python学习笔记4-切片
  11. 数据原理——1、ChIP-seq
  12. 安装VMWare Workstation 12的步骤
  13. Python实现支持人机对战的五子棋软件(超详细)
  14. 分布式系统:FastRPC eRPC
  15. 做工作必须将心比心——感谢译者陈浩对我们的批评
  16. 三星手机com.android.systemservice卸载,完美卸载 系统程序卸载就用System App Remover
  17. 喉炎在临床上的症状表现
  18. 万字长文:功能安全量产落地的三座大山
  19. 祝福我的家人朋友永远平安健康
  20. CMD/DOS学习笔记

热门文章

  1. 【前端知识之JS】JS本地存储
  2. Android Jetpack 库架构组件 Room+Paging 基础使用
  3. 上海花旗软件这个公司怎样?
  4. U盘安装Ubuntu系统血泪总结
  5. ASK调制信号仿真程序
  6. LVS FULLNAT
  7. 信息可视化的经典案例:伦敦地铁线路图
  8. 学术休假之银行储蓄系统
  9. sed 删除某一行_sed 命令删除指定行
  10. 如何在windows开端口