​用栈实现队列【C语言+leetcode】

题一:用栈实现队列

1.链接

232. 用栈实现队列 - 力扣(LeetCode)

 2.思路

这里要求用栈的特性和结构来去实现队列

栈是后进先出,栈的入栈和出栈都是从栈顶开始的

3.代码及解释 

3.1创建栈的结构

若队栈不太请楚的,请看我之前的文章栈和队列详解-CSDN博客 

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

//这是栈
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);
int StackSize(ST* ps);
bool StackEmpty(ST* ps);


void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0; 
	ps->capacity = 0;
}

void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 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, sizeof(STDataTyp)*newCapacity);
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			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];
}

int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
 3.2创建队列的结构

这里会有两个栈

一个栈用来存数据,另一个用来删除数据

此时栈一 ,有五个数据,现在要实现将1给删除掉,由于栈要求要后进先出,那么如果我们将数据 全挪到栈2中,因为栈的特点,故我们先将5给挪到栈2的栈底,然后依次挪,挪到最后的时候,1就在栈2的栈顶,此时可以直接调用栈的函数进行删除,可以将栈2中的数据全删除掉。

故将栈2命名为 popST

要插入数据时,不能插入到栈2中,如果插入到栈2,那么由于栈的性质,会插到数据1的前面,那么就打乱了顺序,故我们要插,只能插到栈1中,故将栈一命名为pushST

typedef struct {
    ST pushST;
    ST popST;

} MyQueue;
 3.3初始化队列

由于队列是由两个栈来构建的,则初始化队列,就相当于先创建好一个MyQueue,然后在初始化两个栈

MyQueue* myQueueCreate()
{
    MyQueue* qe=(MyQueue*)malloc(sizeof(MyQueue));
    StackInit(&qe->pushST);
    StackInit(&qe->popST);
    return qe;
}
3.4实现队列数据的插入

直接往栈pushST里插入数据,实现这一步操作,只需要调用函数StackPush就行

void myQueuePush(MyQueue* obj, int x) {
   StackPush(&obj->pushST,x);
}
 3.5实现返回队列开头的元素

先判断popST是否为空,如果为空,那么就将pushST的数据全移到popST中去,然后在调用函数StackTop来返回队列开头的元素。

int myQueuePeek(MyQueue* obj) {
    if(StackEmpty(&obj->popST))
    {
        while(!StackEmpty(&obj->pushST))
        {
            StackPush(&obj->popST,StackTop(&obj->pushST));
			       StackPop(&obj->pushST);
        }
    }
		return StackTop(&obj->popST);
}
 3.6实现从队列的开头移除并返回元素
int myQueuePop(MyQueue* obj) 
{
     int front=myQueuePeek(obj);//调用函数,来将数据有顺序的导入到popST中
     StackPop(&obj->popST);//删除队列的第一个元素
     return front;//返回队列里第一个数据
}
 3.7判断队列是否为空

由于队列是由两个栈来构建的,判断是否为空,即判断两个栈是否为空

bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->pushST)&&StackEmpty(&obj->popST);
}
 3.8释放队列

由于队列是由两个栈来构建的,销毁队列,即是销毁两个栈

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

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值