小白学算法(10)模拟栈和队列

232 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情

模拟栈和队列

模拟栈

前面已经介绍了静态数组模拟单链表和双链表,那么接下来就开始使用静态数组模拟最常见的几种数据结构,第一是栈,第二是队列

小白学算法(8)区间合并+单链表 - 掘金 (juejin.cn)

小白学算法(9)双链表(静态数组模拟) - 掘金 (juejin.cn)

先回顾下C++里面STL容器中栈的常用方法

push    // 向栈顶插入
pop     // 弹出栈顶元素
top     //取出stack的顶部元素
back()  //返回末尾的元素

所以用数组模拟这四种方法,栈的存储方法 先进后出 ,那么我们可以以数组尾部作为栈顶,从尾部插入然后从尾部弹出,那么就形成了栈

1.模板介绍

//创建数组模拟栈
int stk[N];
//tt作为尾指针
int tt=-1;
void push(int a)
{
    //从尾部插入
    stk[++tt]=a;
}
void pop()
{
    //静态表示弹出,那么就将尾指针向前移
    tt--;
}
bool empty()
{
    //判断此时尾指针是否为初始化,是就为空
    return tt==-1?true:false;
}
int query()
{
    //查询栈顶,就是查询尾指针的数
    return stk[tt];
}

2.实操演练

828. 模拟栈 - AcWing题库

实现一个栈,栈初始为空,支持四种操作:

  1. push x – 向栈顶插入一个数 xx;
  2. pop – 从栈顶弹出一个数;
  3. empty – 判断栈是否为空;
  4. query – 查询栈顶元素。
#include<iostream>
using namespace std;
const int N=1e5+10;
int stk[N];
int tt=-1;
void push(int a)...
void pop()...
bool empty()...
int query()...
int main()
{
    int M;
    cin>>M;
    while(M--)
    {
        string temp;
        cin>>temp;
        if(temp=="push")
        {
         int x;
         cin>>x;
         push(x);
        }else if(temp=="pop")
        {
            pop();
        }else if(temp=="empty")
        {
            bool result=empty();
            string s=(result==true?"YES":"NO");
            cout<<s<<endl;
        }else
        {
            cout<<query()<<endl;
        }
        
    }
    return 0;
}

模拟队列

我们先回顾下队列的性质

先进先出

push // 从队尾插入

pop // 从队头弹出

front // 返回队头元素

back // 返回队尾元素

所以用数组模拟队列,只需要增加一个头指针

1.模板介绍

正常队列

int que[N];
//0 作为头指针 -1 作为尾指针
int hh=0,tt=-1;
void push(int x)
{
    //++tt 作为尾部插入的位置
    que[++tt]=x;
}
void pop()
{
    //弹出与栈一样,只需要移动指针即可,注意栈是尾部插入 头部弹出
    hh++;
}
int query()
{
   return que[hh]; 
}
bool empty()
{
    //初始化 hh=0 tt=-1,后续不为空 tt应该>hh
    if(hh>tt)
    {
        return true;
    }
    return false;
}

循环队列

只是要判断移动到尾部要循环到头部

int que[N];
//循环链表 初始化 头指针与尾指针指向同一个
int hh=0,tt=0;
void push(int x)
{
    //++tt 作为尾部插入的位置
    que[tt++]=x;
    if (tt == N) tt = 0;
}
void pop()
{
    //弹出与栈一样,只需要移动指针即可,注意栈是尾部插入 头部弹出
    hh++;
    if (hh == N) hh = 0;
}
int query()
{
   return que[hh]; 
}
bool empty()
{
    if(hh==tt)
    {
        return true;
    }
    return false;
}

2.实操演练

829. 模拟队列 - AcWing题库

实现一个队列,队列初始为空,支持四种操作:

  1. push x – 向队尾插入一个数 xx;
  2. pop – 从队头弹出一个数;
  3. empty – 判断队列是否为空;
  4. query – 查询队头元素。
#include<iostream>
using namespace std;
const int N=1e5+10;
int que[N];
int hh=0,tt=-1;
void push(int x)...
void pop()...
int query()...
bool empty()...
int main()
{
    int M=0;
    cin>>M;
    while(M--)
    {
        string str;
        cin>>str;
        if(str=="pop")
        {
            pop();
        }else if(str=="push")
        {
            int x;
            cin>>x;
            push(x);
        }else if(str=="empty")
        {
            string s=(empty()==true)?"YES":"NO";
            cout<<s<<endl;
        }else
        {
            cout<<query()<<endl;
        }
    }
    return 0;
}