栈和队列(一)


栈和队列的定义和特点

栈和队列是限定插入和删除只能在表的“端点”进行的线性表。

栈和队列都是线性表,是插入和删除位置受限的线性表

后进先出:栈只能在表尾进行插入删除 Insert(S, n+1, x) Delete(S, n)

栈的应用:数制转换、括号匹配的检验、行编辑程序、迷宫求解、表达式请值、八皇后问题、函数调用、递归调用的实现

队列

先进先出:表尾插入,表头删除 Insert(Q, n+1, x) Delete(Q, 1)

排队问题

栈的定义和特点

栈(stack)是一个特殊的线性表,插入和删除限定在一端(通常是表尾)

后进先出(Last In First Out)的线性表,简称LIFO结构

image-20211204173956378 image-20211125092147994

入栈:插入元素到栈顶(表尾) “入” = 压入 = PUSH

出栈:从栈顶(表尾)删除元素 “出” = 弹出 = POP

image-20211125093945703

注意栈顶位置

存储结构:顺序栈、链栈(顺序栈更常用)

队列的定义和特点

队列(queue)是一种先进先出的线性表。表尾插入、表头删除(排队)

Q = (a1, a2, ··· , an)

image-20211201165052728

逻辑结构:与线性表相同,为一对一关系

存储结构:顺序队、链队(循环顺序队列更常见)

案例引入

进制转换(栈)

十进制整数N向其他进制数d(二、八、十六)转换

转换法则:取余法 先得到的余数是最后一位,最后得到的余数是第一位

image-20211201183624323 image-20211201183841336

括号匹配的检验(栈)

image-20211201184357589

image-20211201184345956

表达式求值(栈)

由运算符优先级确定运算顺序——算符优先算法

image-20211204174119617

设置两个栈:算符栈OPTR:寄存运算符

​ 操作数栈OPND:寄存运算数和运算结果

image-20211204174146837

舞伴问题(队列)

image-20211204174208570

先入队的男士或女士先出队配成舞伴——先进先出特性 -> 队列

image-20211204174241202

栈的表示和操作的实现

栈的抽象数据类型的定义

ADT Stack {
    数据对象:
        D = {ai|ai∈ElemSet(ai是同样性质的),i=1,2,...,n, n≧0(n=0:空栈)}
    数据关系:
        R1 = {<ai-1,ai>|ai-1,ai∈D,i=2,...,n}
        (前趋后继关系)(约定an端为栈顶,a1端为栈底)
    基本操作:
        初始化、进栈、出栈、取栈顶元素等
}
image-20211204174256236
栈的基本操作

InitStack(&S) 初始化操作

操作结果:构造一个空栈S

DestroyStack(&S) 销毁栈操作

初始条件:栈S已存在

操作结果:栈S被销毁

StackEmpty(S) 判定S是否为空栈

初始条件:栈S已存在

操作结果:若栈S为空栈,则返回TRUE,否则FALSE

StackLength(S) 求栈的长度

初始条件:栈S已存在

操作结果:返回S的元素个数,即栈的长度

GetTop(S, &e) 取栈顶元素

初始条件:栈S已存在且非空

操作结果:用e返回S的栈顶元素

ClearStack(&S) 清空栈

初始条件:栈S已存在

操作结果:将S清为空栈

Push(&S, e) 入栈 压栈

初始条件:栈S已存在

操作结果:插入元素e为新的栈顶元素

Pop(&s, &e) 出栈

初始条件:栈S已存在且非空

操作结果:删除栈顶元素an,并用e返回其值

栈的表示和实现

栈是操作受限的线性表

栈的顺序存储——顺序栈

栈的链式存储——链栈

顺序栈的表示和实现

存储方式:同一般线性表的顺序存储结构完全相同

利用一组地址连续的存储单元一次存放自栈底到栈顶的数据元素

设top指针,指示栈顶元素之上的地址

设base指针:指示栈底元素

用stacksize表示栈可使用的最大容量 表示分配的数组大小

image-20211201203203536

image-20211201210417301

空栈:base == top 是栈空标志

image-20211201203731251

栈满:top - base = stacksize

image-20211201205444136

栈满时的处理方法:

  1. 报错
  2. 分配更大的空间,作为栈的存储空间,将原栈的内容移入新栈(该操作费时,万不得已不会做)

顺序栈易产生溢出(数组大小固定)

上溢:栈已经满,又要压入元素

下溢:栈已经空,还要弹出元素

注:上溢是一种错误,使问题的处理无法进行;而下溢一般认为是一种结束条件,即问题处理结束

顺序栈的定义
#define MAXSIZE 100
typedef struct{
    SElemType *base;  //栈底指针
    SElemType *top;  //栈顶指针
    int stacksize;  //栈可用最大容量 数组大小
}SqStack;//顺序栈

image-20211201211800424

top - base = 元素个数 指针相减->差几个元素

顺序栈的基本操作

初始化
Status InitStack(SqStack &S){  //构造一个空栈
    S.base = new SElemType[MAXSIZE];//数组:类型[大小]    
    //S.base = (SElemType*)malloc(MAXSIZE*sizeof(SElemType));//转换为SElenType指针
    if(!S.base) exit(OVERFLOW);//S.base没有值,存储分配失败
    S.top == S.base;  //栈顶指针等于栈底指针
    S.stacksize = MAXSIZE;
    return OK;  
}
判空

top == base

Status StackEmpty(SqStack S){  //若栈为空,返回TRUE;否则返回FALSE
    if(S.top == S.base)
        return TRUE;  
    else 
        return FALSE;
}
求长度
image-20211202213444540

top - base 元素个数

int StackLength(SqStack S)
{
    return S.top - S.base;
}
清空

将top指针指向base,top == base,即可认为是空栈

Status ClearStack(SqStack S){
    if(S.base) S.top == S.base;//栈存在
    return OK;
}
销毁
Status DestoryStack(SqStack &S){
    if(S.base){
        delete S.base; //将数组回归内存
        S.stacksize=0;
        S.base = S.top = NULL;  //将栈结构类型的3个值设置为空
    }
    return OK;
}
入栈
image-20211202215459120
  1. 判满,若满则出错(上溢)
  2. 元素e压入栈顶
  3. 栈顶指针加1
Status Push(SqStack &S, SElemType e){
    if(S.top-S.base == S.stacksize) return ERROR;//栈满
    *S.top = e;//‘*’对指针所指空间操作
    S.top++;
    return OK;
}
出栈
  1. 判空,若空则出错(下溢)
  2. 栈顶指针减1
  3. 获取栈顶元素e
Status Pop(SqStack &S, SElemType &e){
    if(S.top==S.base) //等价于if(StackEmpty(S))  判空
        return ERROR;
    S.top--;
    e = *S.top;
    return OK;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值