LeetCode数据结构题---用栈实现队列

原题链接:用栈实现队列
在这里插入图片描述

思路

栈的特性是先进后出,而队列的特性是先进先出,也就是说,如果把一串数据放进栈里面,它会倒着拿出来,但是队列是会正着拿出来。这里题目给了两个栈,如果我们将数据放到一个栈里面,再从这个栈里面拿出来放到另一个栈里面,那取出来不就是成正的了吗?
为了便于区分,我们将第一个栈命名为pushs,因为入队的数据都必须先放在这个栈里面,第二个栈命名为pops,因为如果要出队或者取最先入队的数据,必须先将第一个栈的数据全部转移到这个栈里面,如果没能全部转移,那么数据就会造成混乱,无法做到先进先出。
在这里插入图片描述

代码实现

  • 既然要用到两个栈,那需要之前写的栈函数:
typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;
//初始化
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		exit(-1);
	}
	ps->capacity = 4;
	//top初始为0,top指向栈顶元素的下一个元素,top初识为-1,top指向栈顶的元素
	ps->top = 0;
}

//销毁
void StackDestory(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)
	{
		STDataType* tmp = realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
		if (tmp == NULL)
		{
			exit(-1);
		}
		else
		{
			ps->a = tmp;
			ps->capacity *= 2;
		}
	}
	ps->a[ps->top] = x;
	ps->top++;
}

//出栈
void StackPop(ST* ps)
{
	assert(ps);
	ps->top--;
}
//取栈顶的数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top>0);
	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;
}
  • 队列用两个栈表示
typedef struct {
    ST pushs;
    ST pops;

} MyQueue;
  • 创建一个队列
MyQueue* myQueueCreate() {
    MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
     if(q==NULL)
    {
        exit(-1);
    }
    StackInit(&q->pushs);//初始化两个栈
    StackInit(&q->pops);
    return q;
}
  • 入队
void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->pushs, x);//这里只需要往pushs栈里面插入即可,需要出队时再插入到pops
}
  • 出队
int myQueuePop(MyQueue* obj) {
     //pops为空说明数据全在pushs中,如果不为空说明pops还有数据,此时栈顶的数据就是先入队的数据
    if(StackEmpty(&obj->pops))
    {
        while(!StackEmpty(&obj->pushs))//pushs队列不为空时执行循环
        {
            StackPush(&obj->pops,StackTop(&obj->pushs));//将pushs队列里的数据放到pops中
            StackPop(&obj->pushs);//销毁pushs队列中栈顶的数据
        }
    }
    int ret=StackTop(&obj->pops);//取出pops栈顶的数据
    StackPop(&obj->pops);//销毁pops栈顶数据
    return ret;
}

在这里插入图片描述

  • 取出前面入队的数据
int myQueuePeek(MyQueue* obj) {
    if(StackEmpty(&obj->pops))
    {
        while(!StackEmpty(&obj->pushs))
        {
            StackPush(&obj->pops,StackTop(&obj->pushs));
            StackPop(&obj->pushs);
        }
    }
    int top=StackTop(&obj->pops);
    return top;
}

这里的实现方式和上一个出队一样,唯一的不同是没有销毁pops栈顶的数据
在这里插入图片描述

  • 检查是否为空
bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->pops)&&StackEmpty(&obj->pushs);
}

只有当pops和pushs都为空时,队列才为空

  • 销毁队列
void myQueueFree(MyQueue* obj) {
    StackDestory(&obj->pops);//销毁pops
    StackDestory(&obj->pushs);//销毁pushs
    free(obj);//释放指针obj
}
  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天也要写bug、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值