Leetcode经典题目之用队列实现栈

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。
P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。

  

1、题目展示

在这里插入图片描述


  前面我们了解过如何实现队列的代码,如果有遗忘或不熟悉可以回看:链接: 队列的实现(使用链表)


  下面我们直接进入正文。



2、题目分析


  在我们的知识储备当中,我们知道,队列是一种先进先出的数据结构,而栈与其相反,是一种后进先出的数据结构,故我们在用队列实现栈的时候,可以使用两个队列来进行操作,从而令其达到栈的功能。

在这里插入图片描述

  对于此我们该如何进行理解,当我们需要向队列中插入数据时十分方便,我们可以任选其中一个进行插入,以q1为例,进行四次数据插入,分别为1,2,3,4。
在这里插入图片描述
  而出数据时,因为队列时先进先出,而我们要实现的功能时将最后一个插入的数据4删除或输出,故此时我们可以将1,2,3以队列出数据的形式输出到q2当中,并将q1当中的1,2,3删除,此时q1中只剩下了数据4,此时便可以将数据输出或直接删除了。
在这里插入图片描述
  当我们需要再次输入输出数据的时候便可以仿照上述模式进行操作,只不过输入时的队列选择不再是q1,而是有数据的那一个队列,当需要输出或删除数据时直接将有数据的队列中不需要操作的数据导入到没有数据的队列当中。这便是插入数据和删除输出数据。


  而题目中我们还需要实现的功能有判断栈是否为空。这一功能便十分简单,之间判断一下两个队列是否都为空即可。代码如下:

bool myStackEmpty(MyStack* obj) 
{
    return QueueEmpty(&(obj->q1)) && QueueEmpty(&(obj->q2));
}




3、完整代码演示


  我们在完成这一道题目时,因为是oj题目,所以在需要完成的功能函数前需要自行书写队列的相关内容代码,故不在此展示,有需要者可在标题1中自行寻找link链接。
typedef int QDataType;

typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType val;
}QNode, * pQNode;


typedef struct Queue
{
	pQNode phead;
	pQNode ptail;
	int size;
}Queue, * pQueue;


//队列初始化
void QueueInit(pQueue pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

//队列销毁
void QueueDestroy(pQueue pq)
{
	assert(pq);
	pQNode cur = pq->phead;
	while (cur)
	{
		pQNode next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

void QueuePush(pQueue pq, QDataType x)
{
	assert(pq);
	pQNode tmp = (pQNode)malloc(sizeof(QNode));
	if (tmp == NULL)
	{
		perror("QueuePush:malloc");
		return;
	}
	tmp->next = NULL;
	tmp->val = x;
	if (pq->ptail == NULL)
	{
		pq->phead = pq->ptail = tmp;
	}
	else
	{
		pq->ptail->next = tmp;
		pq->ptail = tmp;
	}
	pq->size++;
}

void QueuePop(pQueue pq)
{
	assert(pq);
	assert(pq->size != 0);
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		pQNode tmp = pq->phead->next;
		free(pq->phead);
		pq->phead = tmp;
	}
	pq->size--;
}

bool QueueEmpty(pQueue pq)
{
	assert(pq);
	return pq->size == 0;
}

QDataType QueueBack(pQueue pq)
{
	assert(pq);
	assert(pq->size != 0);
	return pq->ptail->val;
}

//取队列头数据
QDataType QueueFront(pQueue pq)
{
	assert(pq);
	assert(pq->size != 0);
	return pq->phead->val;
}

//队列数据个数
int QueueSize(pQueue pq)
{
	assert(pq);
	return pq->size;
}

typedef struct 
{
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() 
{
    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
    QueueInit(&(obj->q1));
    QueueInit(&(obj->q2));
    return obj;
}

void myStackPush(MyStack* obj, int x) 
{
    if(!QueueEmpty(&(obj->q1)))
    {
        QueuePush(&(obj->q1),x);
    }    
    else
    {
        QueuePush(&(obj->q2),x);
    }
}

int myStackPop(MyStack* obj) 
{
    Queue* empty = &(obj->q1);
    Queue* nonempty = &(obj->q2);
    if(QueueEmpty(&(obj->q2)))
    {
        empty = &(obj->q2);
        nonempty = &(obj->q1);
    }
    while(QueueSize(nonempty) > 1)
    {
        QueuePush(empty,QueueFront(nonempty));
        QueuePop(nonempty);
    }
    int tmp = QueueFront(nonempty);
    QueuePop(nonempty);
    return tmp;
}

int myStackTop(MyStack* obj) 
{
    if(!QueueEmpty(&(obj->q1)))
        return QueueBack(&(obj->q1));
    else
        return QueueBack(&(obj->q2));
}

bool myStackEmpty(MyStack* obj) 
{
    return QueueEmpty(&(obj->q1)) && QueueEmpty(&(obj->q2));
}

void myStackFree(MyStack* obj) 
{
    QueueDestroy(&(obj->q1));
    QueueDestroy(&(obj->q2));
    free(obj);    
}




4、结语


  十分感谢您观看我的原创文章。
  本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
  如需引用,注明地址。
;

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值