栈和队列知识总结

本文详细介绍了栈和队列的基本概念、基本运算以及它们的两种存储结构——顺序存储和链式存储。同时,展示了C++中使用STL实现栈和队列的方法。此外,还提及了栈的应用,如最小栈问题,以及使用队列实现栈的挑战。
摘要由CSDN通过智能技术生成

一、栈

(一)栈的定义和基本运算

1.栈的定义

栈是一种只能在一端进行插入或删除操作的线性表,也称为后进后出表。

相关的概念包括“栈顶”、“栈底”、“空栈”、“进栈/入栈”、“出栈/退栈”等。

n个不同元素通过一个栈产生的出栈序列的个数为 \frac{1}{n+1}C_{2n}^{n} 。

2.基本运算

初始化栈InitStack(&s):构造一个空栈s。

销毁栈DestroyStack(&s):。释放栈s占用的存储空间。

判断栈是否为空StackEmpty(s):若栈s为空,则返回真;否则返回假。

进栈Push(&S,e):将元素e插入到栈s中作为栈顶元素。

出栈Pop(&s,&e):从栈s中退出栈顶元素,并将其值赋给e。

取栈顶元素GetTop(s,&e):返回当前的栈顶元素,并将其值赋给e。

(二)栈的顺序存储结构

1.顺序栈的存储和声明

 可用下列方式来声明顺序栈的类型SqStack:

typedef struct{
    ElemType data[MaxSize];
    int top;
} SqStack;

栈空条件:top=-1

栈满条件:top=MaxSize-1

2.部分基本运算的实现

(1)初始化栈:采用栈指针s指向一个空栈

void InitStack(SqStack *&s){
    s=(SqStack *)malloc(sizeof(SqStack));
    s->top=-1;
}

(2)进栈

bool Push(SqStack *&s,ElemType e){
    if(s->top==MaxSize-1)
        return false;
    s->top++;
    s->data[s->top]=e;
    return true;
}

(3)出栈

bool Pop(SqStack *&s,ElemType &e){
    if(s->top==-1)
        return false;
    e=s->data[s->top];
    s->top--;
    return true;
}

3.共享栈

typedef struct{
    ElemType data[MaxSize];
    int top1,top2;
} DStack;

栈空条件:栈1空为top1==-1,栈2空为top2=MaxSize.

栈满条件:top1=top2-1;

进栈操作:进栈1为top1++;data[top1]=x;进栈2为top2--;data[top2]=x。

出栈操作:出栈1为x=data[top1];top1--;出栈2为x=data[top2];top2++。

(三)栈的链式存储结构

1.链栈的存储和声明

 链栈中结点类型LinkStNode的声明如下:

typedef struct linknode{
    ElemType data;
    struct linknode *next;
} LinkStNode;

栈空条件:s->next==NULL

栈满条件:只有内存溢出才会栈满,一般不考虑

2.部分基本运算的实现

(1)初始化栈

void InitStack(LinkStNode *&s){
    s=(LinkStNode *)malloc(sizeof(LinkStNode));
    s->next=NULL;
}

(2)进栈

bool Push(LinkStNode *&s,ElemType e){
    LinkStNode *p;
    p=(LinkStNode *)malloc(sizeof(LinkStNode));
    p->data=e;
    p->next=s->next;
    s->next=p;
    return true;
}

(3)出栈

bool Pop(LinkStNode *&s,ElemType &e){
    LinkStNode *p;
    if(s->next==NULL)
        return false;
    p=s->next;
    e=p->data;
    s->next=p->next;
    free(p);
    return true;
}

(四)C++ STL 栈的实现

#include<stack>          //头文件
stack<ElemType> name;    //stack的定义
s.empty();               //栈空返回true 否则false
s.push(x);               //将x入栈
s.pop();                 //将栈顶元素出栈
s.top();                 //返回栈顶元素
s.size();                //返回栈中元素的个数

二、队列

(一)队列的定义和基本运算

1.队列的定义

队列简称队,是一种仅允许在表的一端进行插入操作,而在表的另一端进行删除操作的线性表,也称为先进先出表。

相关的概念包括“队尾”、“队头/队首”、“进队/入队”、“出队/离队”等。

2.基本运算

初始化队列InitQueue(&q):构造一个空队列q。

销毁队列DestroyQueue(&q):释放队列q占用的存储空间。

判断队列是否为空QueueEmpty(q):若队列q为空,则返回真;否则返回假。.

进队列enQueue(&q,e):将元素e进队作为队尾元素。

出队列deQueue(&q,&e):从队列q中出队一个元素,并将其值赋给e。

(二)队列的顺序存储结构

1.顺序队的存储和声明

 顺序队类型SqQueue声明如下:

typedef struct{
    ElemType data[MaxSize];
    int front,rear;
}

队空条件:q->front==q->rear

队满条件:q->rear==MaxSize-1

2.部分基本运算的实现

(1)初始化队列

void InitQueue(SqQueue *&q){
    q=(SqQueue *)malloc(sizeof(SqQueue));
    q->front=q->rear=0;
}

(2)进队列

bool enQueue(SqQueue *&q,ElemType e){
    if(q->rear==MaxSize-1)
        return false;
    q->rear++;
    q->data[q->rear]=e;
    return true;
}

(3)出队列

bool deQueue(SqQueue *&q,ElemType &e){
    if(q->front==q->rear)
        return false;
    q->front++;
    e=q->data[q->front];
    return true;
}

3.环形队列

环形队列首尾相连后,当队尾指针rear=MaxSize-1后,在前进一个位置就到达0,就可以用另一端的空位置存放队列元素,可以采用数学上的求余运算来实现:

队头指针front循环增1:front=(front+1)%MaxSize;

队尾指针rear循环增1:rear=(rear+1)%MaxSize;

(三)队列的链式存储结构

1.链队的存储和声明

 链队中数据节点的类型DataNode声明如下:

typedef struct qnode{
    ElemType data;
    struct qnode *next;
} DataNode;

链队头结点(或链队结点)的类型LinkQuNode声明如下:

typedef struct{
    DataNode *front;
    DataNode *rear;
} LinkQuNode;

队空条件:q->rear==NULL(或q->front==NULL)

队满条件:不考虑

2.部分基本运算的实现

(1)初始化队列

void InitQueue(LinkQuNode *&q){
    q=(LinkQuNode *)malloc(sizeof(LinkQuNode));
    q->front=q->rear=NULL;
}

(2)销毁队列

void DestroyQueue(LinkQuNode *&q){
    DataNode *pre=q->front,*p;
    if(pre!=NULL){
        p=pre->next;
        while(p!=NULL){
            free(pre);
            pre=p;
            p=p->next;
        }
        free(pre);
    }
    free(q);
}

(3)进队列

bool enQueue(LinkQuNode *&q,ElemType e){
    DataNode *p;
    p=(DataNode *)malloc(sizeof(DataNode));
    p->data=e;
    p->next=NULL;
    if(q->rear==NULL)
        q->front=q->rear=p;
    else{
        q->rear->next=p;
        q->rear=p;
    }
    return true;
}

(4)出队列

bool deQueue(LinkQuNode *&q,ElemType &e){
    DataNode *t;
    if(q->rear==NULL)
        return false;
    t=q->front;
    if(q->front==q->rear)
        q->front=q->rear=NULL;
    else
        q->front=q->front->next;
    e=t->data;
    free(t);
    return true;
}

(四)C++ STL 队列的实现

#include <queue>        //头文件
queue<ElemType> name;   //queue的定义
q.empty();              //队列为空时返回true,否则返回false
q.push(x);              //入队操作,将x插入到队列
q.pop();                //出队操作,删除队头元素
q.front();              //返回队头元素
q.back();               //返回队尾元素
q.size();               //返回队列中元素的个数

三、栈和队列的应用

155.最小栈

设计一个支持 push ,pop ,top 操作,并能在 常数时间 内检索到最小元素的栈。

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。

227.基本计算器 II

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

整数除法仅保留整数部分。

你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

提示:1 <= s.length <= 3 * 105,s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开,s 表示一个 有效表达式,表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内,题目数据保证答案是一个 32-bit 整数

225.用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。

int pop() 移除并返回栈顶元素。

int top() 返回栈顶元素。

boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

STRANGEX-03

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

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

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

打赏作者

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

抵扣说明:

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

余额充值