[数据结构] 用两个栈实现队列详解

news/2025/2/9 11:00:57/

文章目录

一、栈实现队列的特点分析

1、1 具体分析

1、2 整体概括

二、用栈模拟队列代码的实现

2、1 手撕 栈 代码

2、1、1 stack.h

2、1、2 stack.c

2、2 用栈实现队列代码


🙋‍♂️ 作者:@Ggggggtm 🙋‍♂️

👀 专栏:数据结构与算法、高频面试问题 👀

💥 标题:用栈模拟队列 💥

 ❣️ 寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景 ❣️

  在数据结构中,栈和队列是较为常见的两种数据结构。他们各有自己的特点:栈是后进先出原则,队列是先进先出原则。那怎么用栈去实现队列呢?此问题在面试中也是高频出现的问题。本篇文章会给出详细解释。

一、栈实现队列的特点分析

1、1 具体分析

  队列和栈在插入数据时,队列是从队尾进行插入栈是从栈顶插入。但是他们的删除数据是不同的。我们知道队列的特点是:先新先出 ,删除数据是在对头进行删除,栈的特点是:先进后出,也就是在栈顶进行删除。

  当我们用栈实现队列时,最根本的也是最重要的是需要解决删除的问题。我们用栈实现队列时,在栈中的删除就不是删除栈顶的元素了,我们需要根据队列的特点进行删除,也就是我们需要删除的是栈底的元素  怎么删除栈底的元素呢?在这里我们需要两个栈,分别命名为push栈pop栈。我们先把元素的插入全部插入到push栈中,当需要删除时,我们首先把push栈中的元素全部导入到pop栈中,此时的pop栈中的栈顶元素,相当于我们要删除的对头元素了。

  那如果我们想要接着插入呢?我们接着往push栈中插入即可。删除的话我们看pop栈中是否有元素,如果pop栈不为空,就接着删除如果pop栈为空,我们需要把push栈的元素再次导入到pop栈中删除即可。具体流程我们可以结合下图(gif)理解: 

1、2 整体概括

  用栈模拟队列我们整体的思路分为以下几步:

  • 我们需要先定义两个栈,分别为push栈和pop栈;
  • 插入数据到往push栈中;
  • 删除数据时,需要先判断pop栈是否为空。如果为空,需要将push栈的所有数据导入到pop栈中。如果不为空,就直接在pop栈删除即可。
  • 再插入数据时,就往push栈中插入即可。

  以上即为用栈模拟队列的全过程,那我们来看代码的实现。

二、用栈模拟队列代码的实现

  这里我们用c语言进行实现。所以我们这里需要先手撕出一个栈。

2、1 手撕 栈 代码

2、1、1 stack.h

#define INT_CAPACITY 4
typedef int STDataType;typedef struct stack
{STDataType* a;int top;int capacity;
}ST;void STInit(ST* ps);
void STDestory(ST* ps);bool STIsEmpty(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
int STSize(ST* ps);STDataType STTop(ST* ps);

2、1、2 stack.c

void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType)* INT_CAPACITY);if (ps->a == NULL){perror("malloc fail");exit(-1);}ps->top = 0;ps->capacity = INT_CAPACITY;
}
void STDestory(ST* ps)
{assert(ps);free(ps->a);ps->capacity = 0;ps->top = 0;
}bool STIsEmpty(ST* ps)
{assert(ps);return ps->top==0;
}
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity *= 2;}ps->a[ps->top++] = x;
}
void STPop(ST* ps)
{assert(ps);assert(!STIsEmpty(ps));ps->top--;
}
int STSize(ST* ps)
{assert(ps);return ps->top;}STDataType STTop(ST* ps)
{assert(ps);assert(!STIsEmpty(ps));return ps->a[ps->top - 1];
}

2、2 用栈实现队列代码

这个是OJ链接( 用栈实现队列 - OJ链接(力扣)),大家可以直接点开链接用其他语言做一下。我们看C语言的代码实现。

#define INT_CAPACITY 4
typedef int STDataType;typedef struct stack
{STDataType* a;int top;int capacity;
}ST;void STInit(ST* ps);
void STDestory(ST* ps);bool STIsEmpty(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
int STSize(ST* ps);STDataType STTop(ST* ps);void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType)* INT_CAPACITY);if (ps->a == NULL){perror("malloc fail");exit(-1);}ps->top = 0;ps->capacity = INT_CAPACITY;
}
void STDestory(ST* ps)
{assert(ps);free(ps->a);ps->capacity = 0;ps->top = 0;
}bool STIsEmpty(ST* ps)
{assert(ps);return ps->top==0;
}
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity *= 2;}ps->a[ps->top++] = x;
}
void STPop(ST* ps)
{assert(ps);assert(!STIsEmpty(ps));ps->top--;
}
int STSize(ST* ps)
{assert(ps);return ps->top;}STDataType STTop(ST* ps)
{assert(ps);assert(!STIsEmpty(ps));return ps->a[ps->top - 1];
}typedef struct 
{ST StackPop;ST StackPush;
} MyQueue;MyQueue* myQueueCreate()
{MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->StackPop);STInit(&obj->StackPush);return obj;
}void myQueuePush(MyQueue* obj, int x) 
{STPush(&obj->StackPush,x);
}int myQueuePeek(MyQueue* obj) 
{if(STSize(&obj->StackPop)==0){while(STSize(&obj->StackPush)!=0){STPush(&obj->StackPop,STTop(&obj->StackPush));STPop(&obj->StackPush);}}return STTop(&obj->StackPop);
}int myQueuePop(MyQueue* obj) 
{int ret=myQueuePeek(obj);STPop(&obj->StackPop);return ret;
}bool myQueueEmpty(MyQueue* obj) 
{return STSize(&obj->StackPop)==0 && STSize(&obj->StackPush)==0;
}void myQueueFree(MyQueue* obj) 
{STDestory(&obj->StackPop);STDestory(&obj->StackPush);free(obj);
}

http://www.ppmy.cn/news/35260.html

相关文章

ES6新特性--Set集合

Set集合(1).Set集合概述 ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯 一的,集合实现了 iterator 接口,所以可以使用【扩展运算符】 和【for…of…】进 行遍历 。 (2).Set集合的声明 //集合的声明 let s = new Set(); //声明的时候同时初始化,可以传…

STM-32:按键控制LED灯 程序详解

目录一、基本原理二、接线图三、程序思路3.1库函数3.2程序代码注:一、基本原理 左边是STM322里电路每一个端口均可以配置的电路部分,右边部分是外接设备 电路图。 配置为 上拉输入模式的意思就是,VDD开关闭合,VSS开关断开。 浮空…

English Learning - L2 第 9 次小组纠音 辅音 [s] [z] [ʃ] [ʒ] [h] [ʧ] [ʤ] 2023.3.25 周六

English Learning - L2 第 9 次小组纠音 辅音 [s] [z] [ʃ] [ʒ] [h] [ʧ] [ʤ] 2023.3.25 周六共性问题babies /ˈbeɪbɪz/Zoo /zuː/jazz /ʤz/reads /riːdz/slowly /ˈsləʊli/shop /ʃɒp/delicious /dɪˈlɪʃəs/usually /ˈjuːʒʊəlɪ/whole /həʊl/help /help/…

adb常用指令

echo mem > /sys/power/state // kernel休眠echo on > /sys/power/state //kernel唤醒-------------------------------------------------adb shell pm list packages -f // 查看所有应用位置adb shell pm path 包名 //列出指定包名的apk位置adb shell pm list packages…

010-Ansible数组

定义: 最终都需要将定义的数组转换为列表(list)类型进行操作。 使用yaml语法定义数组 - name: Define an array using YAML syntaxset_fact:my_array: [value1, value2, value3]使用空格分隔的字符串定义数组 - name: Define an array using space-separated st…

Java中Static关键字的五种用法详解

Static的五种用法大致如下: 修饰成员变量,使其成为类变量,也叫静态变量修饰成员方法,使其成为类方法修饰内部类,使其成为静态内部类静态代码块静态导包 直接一点,static关键字就是把属性和方法变为类相关&…

python 使用pyshp读写shp文件

安装 pip install pyshp 引入 import shapefile读取 sfshapefile.Reader("{路径名}",encodingutf-8) # 仅仅读取 shapes与shape shapessf.shapes() 返回值是一个列表,包含该文件中所有的”几何数据”对象shapesf.shape(0) Shape是第1个”几何数据”…

【TopK问题】——用堆实现

文章目录一、TopK问题是什么二、解决方法三、时间复杂度一、TopK问题是什么 TopK问题就是从1000个数中找出前K个最大的数或者最小的数这样的类似问题。 不过并不要求这k个数字必须是有序的,如果题目有要求,则进行堆排序即可。 还有比如求出全国玩韩信…