【leetcode】232. 用栈实现队列

1.使用两个栈结构构建队列

我们需要自定义栈及其相关操作

栈结构遵循后入先出的原则,队列结构遵循先入先出的原则

构建具有两个栈结构的队列,栈pushST用于数据的插入,栈popST用于数据的删除

为栈结构动态开辟空间并初始化栈结构

//定义一个具有两个栈的队列结构
typedef struct {
    ST pushST;//插入数据栈
    ST popST;//删除数据栈

} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
		//内存开辟失败
		if(obj == NULL)
		{
			perror("malloc fail");
			exit(-1);
		}
		//开辟成功,初始化
		else
		{
			StackInit(&obj->pushST);
			StackInit(&obj->popST);
		}
			return obj;

}

2.入队操作

模拟入队操作,即将所有元素压栈即可,这里我们将数据压入栈pushST

void myQueuePush(MyQueue* obj, int x) {
		//把数据压入插入数据专用栈
		StackPush(&obj->pushST,x);

}
3.出队操作

模拟队列的出队操作:队列出队访问的是队头数据,即先进入结构的数据,在栈中即为栈底元素,要访问栈底元素,需要后入的元素先出栈才能访问

以上操作后,栈pushST和栈popST的结构如下:

此时栈pushST的栈顶元素即模拟队列的队头元素,存储并出栈即可

以上操作进行完之后需要将栈popST中的数据还原回pushST吗?

分析:不需要将栈popST中的数据还原回pushST,当进行下一次模拟出队操作时,只需要访问栈popST的栈顶元素即可,栈popST栈顶的元素为先进入栈pushST的元素;若popST为空,则重新进行上述步骤即可

📖Note:

栈结构遵循先进先出的原则,当我们把pushST栈中的元素依次出栈再入栈popST时,元素入栈popST顺序刚好与之前的入栈pushST的先后顺序相反,从而使这些元素出栈popST时栈顶刚好是先入栈pushST的元素

//将pushST中元素外依次倒入popST
void pushSTPopST(MyQueue* obj)
{
		if(StackEmpty(&obj->popST))
		{
			while(!StackEmpty(&obj->pushST))
			{
				StackPush(&obj->popST,StackTop(&obj->pushST));
				StackPop(&obj->pushST);
			}
		}
}

int myQueuePop(MyQueue* obj) {
		pushSTPopST(obj);

		int front = StackTop(&obj->popST);
		StackPop(&obj->popST);
		return front;
}

4.访问队列的开头元素

队列的开头元素即pushST栈中的栈底元素,将栈pushST中的所有元素入到栈popST中,再访问栈popST的栈顶元素即可

int myQueuePeek(MyQueue* obj) {
		pushSTPopST(obj);
    
		return StackTop(&obj->popST);
}

5.判断队列是否为空

队列结构为两个栈结构构成的,当两个栈都为空的时候,队列即为空

bool myQueueEmpty(MyQueue* obj) {

    return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
}

6.空间释放

构建的队列结构动态开辟了空间,所有操作结束后,需要释放空间,否则会造成内存泄漏

void myQueueFree(MyQueue* obj) {
    StackDestroy(&obj->pushST);
    StackDestroy(&obj->popST);
}

参考代码如下:

//栈的相关定义
typedef int STDataType;
//动态内存开辟
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

//初始化
void StackInit(ST* ps);
//销毁
void StackDestroy(ST* ps);
//插入数据
void StackPush(ST* ps, STDataType x);
//删除数据
void StackPop(ST* ps);
//访问栈顶数据
STDataType StackTop(ST* ps);
//判断是否为空栈
bool StackEmpty(ST* ps);
//访问栈中数据
void StackPopAll(ST* ps);
//计算栈的大小
int StackSize(ST* ps);

//初始化
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}
//销毁
void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}
//插入数据
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : (ps->capacity) * 2;
		STDataType* tmp = realloc(ps->a, newcapacity * sizeof(STDataType));
		//扩容失败
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		//扩容成功
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	//插入数据
	ps->a[ps->top] = x;
	ps->top++;
}
//删除数据
void StackPop(ST* ps)
{
	assert(ps);
	//栈不为空才能删除
	assert(!StackEmpty(ps));
	--ps->top;
}
//访问栈顶数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	//栈不为空才能访问
	assert(!StackEmpty(ps));
	return ps->a[ps->top - 1];
}
//判断是否为空栈
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
//计算栈的大小
int StackSize(ST* ps) 
{
	assert(ps);
	return ps->top;
}

//定义一个具有两个栈的队列结构
typedef struct {
    ST pushST;//插入数据栈
    ST popST;//删除数据栈

} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
		//内存开辟失败
		if(obj == NULL)
		{
			perror("malloc fail");
			exit(-1);
		}
		//开辟成功,初始化
		else
		{
			StackInit(&obj->pushST);
			StackInit(&obj->popST);
		}
			return obj;

}

void myQueuePush(MyQueue* obj, int x) {
		//把数据压入插入数据专用栈
		StackPush(&obj->pushST,x);

}
//将pushST中元素外依次倒入popST
void pushSTPopST(MyQueue* obj)
{
		if(StackEmpty(&obj->popST))
		{
			while(!StackEmpty(&obj->pushST))
			{
				StackPush(&obj->popST,StackTop(&obj->pushST));
				StackPop(&obj->pushST);
			}
		}
}

int myQueuePop(MyQueue* obj) {
		pushSTPopST(obj);

		int front = StackTop(&obj->popST);
		StackPop(&obj->popST);
		return front;
}

int myQueuePeek(MyQueue* obj) {
		pushSTPopST(obj);
    
		return StackTop(&obj->popST);
}

bool myQueueEmpty(MyQueue* obj) {

    return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
}

void myQueueFree(MyQueue* obj) {
    StackDestroy(&obj->pushST);
    StackDestroy(&obj->popST);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值