开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
数据结构
第三章
第一节 栈和队列的定义及特点
栈
定义:
- 栈是一个 特殊 的线性表,是只能在一端(通常是表尾)进行删除和插入操作的线性表。
- 也叫 后进先出(Last In First Out) 的线性表,简称 LIFO 结构。
例如:碗的堆放,先放的在最下面,后放的在最上面,要取的时候,就只能从最上面的取
相关概念
- 表尾称为;
- 表头称为;
- 插入元素到栈顶的操作叫做(也可以叫做压栈(push))。
- 从栈顶删除一个元素的的操作叫做(也可以叫做弹栈(pop))。
用图形表示如图:
入栈表示如图:
出栈表示如图:
思考:假设有3个元素a,b,c,入栈的顺序是a,b,c,则它们的出栈顺序有几种可能?
总结:
- 定义:只能在表的一端进行插入和删除操作的特殊线性表;
- 逻辑结构:和线性表一样,都是一对一(有前驱和后继节点);
- 存储结构:可使用顺序栈和链栈;
- 运算规则:只能在栈顶计算,访问节点需要满足后进先出(LIFO)的规则;
- 栈与一般线性表的区别:
- 逻辑结构上:
- 一般线性表: 一对一
- 栈: 一对一
- 存储结构上:
- 一般线性表: 顺序表、链表
- 栈: 顺序栈、链栈
- 运算规则上:
- 一般线性表: 随机存取
- 栈: 后进先出
队列
定义:
- 队列是一种 先进先出(First In First Out----FIFO) 的特殊线性表。
- 在表一端的插入(表尾),另一端删除(表头)。
例如排队就是一种队列的表示,后来的排在队尾,先来的到头部
由于队列和栈类似,不作详细展开
总结:
- 定义:只能在表的一端进行插入,表的另一端进行删除的线性表;
- 逻辑结构:和线性表一样,都是一对一(有前驱和后继节点);
- 存储结构:可使用顺序队和链队;
栈和队列案例举例
- 把十进制159转为八进制。
- 括号匹配的校验。
- 舞伴问题。
栈的抽象数据类型的类型定义
栈的表示和实现
采用顺序栈实现
概念
- 空栈:栈顶和栈底在;
- 栈满:栈顶减去栈底的差值;
- 对于栈满之后的做法,可以;,不再添加后续的元素;也可以,将元素放到新的栈中。
顺序栈的特点
简单,方便,但是易溢出。
- 上溢(overflow):栈已经满了,还要继续压入元素;
- 下溢(underflow):栈已经空了,还要继续弹出元素;
栈的基本操作
定义一个顺序栈
#define MaxSize 100
typedef struct{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;
初始化顺序栈
#include <stdio.h>
#include <malloc.h>
#include <math.h>
typedef int ElemType;
typedef struct{
ElemType base;//栈底
ElemType top;//栈顶
ElemType *value;
ElemType StackSize;
}SqStack;
void initStack(SqStack *q,ElemType length){
q->value=(SqStack *)malloc(sizeof(SqStack)*length);//初始化顺序栈q大小
q->top=q->base=-1;
q->StackSize=length;
}
清空顺序栈
void clearStack(SqStack *q){
if(q->top!=-1){
q->top=q->base;
q->StackSize=0;
}
}
销毁顺序栈
void destoryStack(SqStack *q){
free(q);
q->StackSize=0;
q->value=NULL;
q->base=q->top=-1;
}
顺序表的入栈
void pushStack(SqStack *q,ElemType e){
printf("当前栈大小:%d",q->top);
if(q->top>=q->StackSize-1){
printf("栈空间已满");
}else{
q->value[++q->top]=e;
}
}
顺序栈的出栈
void popStack(SqStack *q){
for(;q->top!=q->base;q->top--){
printf("出栈:%d\n",q->value[q->top]);
}
printf("栈是空的");
}