用栈实现队列(C语言)

目录

题目

题目分析

链接: 题目

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾

int pop() 从队列的开头移除并返回元素

int peek() 返回队列开头的元素

boolean empty() 如果队列为空,返回 true ;否则,返回 false

根据题目,我们可以知道,我们需要用两个栈来实现队列, 的出入规则是后进先出 ,而队列 的出入规则是先进先出

如果我们现在又两个栈,pushpstpopst,先在pushst中入4个数据(4,3,2,1)。

如果我们要出数据的话,我们根据队列的出入原则,应该出数据1,所以我们可以把pushst里面的数据全部倒入到popst中,那么popst中的数据为(1,2,3,4).

如图:

如果需要出数据的话,直接按照顺序出就可以了。
那么,问题来了,我们要入数据,需要在哪个栈里面入?

答案是pushst.如果我们要入数据(5,6).

pushst拿来入数据,popst拿来出数据,刚好可以满足队列的需求。先出四个数据。

想再出数据时,已经没有数据了,我们需要从pushst里再次倒入数据(5,6),

再依此类推...

代码

栈的实现

我们实现栈使用的是数组。

结构体。

先创建一个结构体

c 复制代码
typedef int STDataType;
typedef struct stack
{
	STDataType* a;
	int top;//栈当前大小
	int capacity;//栈的大小
}ST;

栈的初始化

c 复制代码
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;
}

栈的销毁

c 复制代码
void STDestory(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->capacity = pst->top = 0;
}

入栈

c 复制代码
void Push(ST* pst, STDataType x)
{
	assert(pst);
	if (pst->top == pst->capacity)//如果栈的空间不够了,我们需要扩容。
	{
		int newnode = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newnode);
		if (tmp == NULL) {
			perror("realloc:fail");
		}
		pst->a = tmp;
		pst->capacity = newnode;
	}
	pst->a[pst->top++] = x;
}

删除

c 复制代码
void Pop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;//只需要顶部删除即可
}

查找顶部数据

c 复制代码
STDataType Top(ST* pst)
{
	return pst->a[pst->top-1];
}

判空

c 复制代码
bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;
}

答案

我们需要先创建两个栈的结构体

结构体

c 复制代码
typedef struct {
    ST pushst;
    ST popst;
} MyQueue;

初始化

c 复制代码
MyQueue* myQueueCreate() {
    MyQueue * obj = (MyQueue*)malloc(sizeof(MyQueue));
    STInit(&obj->pushst);//对每一个队列进行初始化
    STInit(&obj->popst);
    return obj;
}

插入数据

c 复制代码
void myQueuePush(MyQueue* obj, int x) {
    Push(&obj->pushst,x);//只需要往pushst里面插入就可以了
}

删除数据

先对popst判空,如果为空,我们需要倒入数据后,再删除数据。

c 复制代码
int myQueuePop(MyQueue* obj) {
    if(STEmpty(&obj->popst))
    {
     while(!STEmpty(&obj->pushst))
        {
            Push(&obj->popst,Top(&obj->pushst));
            Pop(&obj->pushst);//倒入一个,记得删除一个
        }
    }
      int top = Top(&obj->popst);//获取顶部苏数据
        Pop(&obj->popst);//删除顶部数据
        return top;
}

获取队列开头元素

跟myQueuePop(MyQueue* obj)函数类似

c 复制代码
int myQueuePeek(MyQueue* obj) {
   
     if(STEmpty(&obj->popst))
    {
     while(!STEmpty(&obj->pushst))
        {
            Push(&obj->popst,Top(&obj->pushst));
            Pop(&obj->pushst);
        }
    }
    return Top(&obj->popst);
}

判空

两个栈为空,队列才为空。

c 复制代码
bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->popst) && STEmpty(&obj->pushst);
}

销毁栈

先要对连个队列进行销毁,再对两个栈的结构体销毁。

c 复制代码
void myQueueFree(MyQueue* obj) {
    STDestory(&obj->popst);
    STDestory(&obj->pushst);
    free(obj);
}
相关推荐
繁星璀璨G2 分钟前
C++11标准模板(STL)- 常用数学函数 - 计算e的给定幂 (ex)(std::exp, std::expf, std::expl)
开发语言·c++·算法·stl·计算e的给定幂
阑梦清川31 分钟前
C++初阶-list用法总结
开发语言·c++·stl·list
wheeldown38 分钟前
【数据结构&&C语言】【入门】【首次万字详细解析】入门阶段数据结构可能用到的C语言知识,一章让你看懂数据结构!!!!!!!
c语言·开发语言·数据结构
小麦黑客笔记1 小时前
2024年三个月自学手册 网络安全(黑客技术)
开发语言·网络·安全·web安全·网络安全
s_little_monster1 小时前
【C++】模版进阶
开发语言·c++·经验分享·笔记·学习·学习方法
Stanford_11061 小时前
C++入门基础知识79(实例)——实例 4【求商及余数】
开发语言·前端·javascript·c++·微信小程序·twitter·微信开放平台
繁依Fanyi1 小时前
828华为云征文|华为Flexus云服务器打造《我的世界》游戏服务器
java·服务器·开发语言·python·算法·华为·华为云
2402_857589361 小时前
Java免税商品购物商城:Spring Boot实现详解
java·开发语言·spring boot
changan2772 小时前
(笔记自用)LeetCode:快乐数
c语言·数据结构·笔记·算法·leetcode·哈希算法
极客小张2 小时前
从图像处理到字符识别:基于STM32与C语言的车牌识别系统实现
c语言·图像处理·人工智能·stm32·物联网·毕业设计·课程设计