一:题目
二:思路
1:先看两个概念:
更清晰的对比:
理解这两张图的不同对题目的一个函数( 返回栈顶元素) 会更好做
由图可知 :
返回栈顶函数即返回队列队尾即可
2:题目的理解
用两个队列来实现栈(表面)
用队列的函数来实现栈(深层)
用先进先出的队列函数 来实现后进先出的栈函数 (本质)
3:思路讲解
第一步:
实现栈(后进先出)的出栈,那我们要把队列1的5出掉,但是我们队列(先进先出)只能出1,这个时候,空队列(队列2)就派上用场了。
第二步:
因为队列1只能按照1 2 3 4 5 的顺序来出队列,那我们就先把1 2 3 4放进队列2中。
本质是对队列1使用出队列函数,将出队列1的元素,再用入队列函数入到2中
第三步:
然后再用队列函数出掉5就行,就达到了对原队列 1 2 3 4 5 的出5 的效果了(栈的后进先出) 。
全程使用的都是队列的函数,最后实现了栈的效果
4:思路要点
a:
不为空队列:用来正常的存储数据,将前n-1个元素给空队列后,自己出掉最后的一个元素
为空队列:在实现出栈(出最后一个元素)的时候,空队列接收非空队列的前n-1个元素
所以我们要保证一个队列是空,一个队列不为空!才能够反复的进行出栈,
所以两个队列会交替使用,交替的成为空队列
注意:
写代码之前,我们得先把队列的实现 放在答题代码的前面
关于队列的实现函数,博主已经在前文队列的实现(一篇包懂)-CSDN博客中讲解了,并且已经在此题中应用且通过此题啦,所以放心使用吧!
三:代码展示及其解释
一:myStackCreate(创建栈) 和MyStack 结构体的实现
解释:
1:
因为要求用两个队列来实现栈,所以我们创建两个队列q1,q2
二:myStackPush函数(入栈)
解释:
1:
push,也就是入栈,根据我们前面的思路,我们是存储到非空队列上的 ,所以我们用队列实现中的判断队列是否为空函数QueueEmpty来找出非空的队列,找到后就将数据存储到非空队列中。
三:myStackPop函数(出栈)
解释:
1:根据前文思路,要区分开空队列和非空队列(QueueEmpty),然后将非空队列的前n-1(除了最后一个),移到空队列中,再将非空队列中的最后一个进行出队列,就达到了出栈的效果(后进先出)
2:也就是将非空队列中的前n-1个,用出队列函数(QueueFront)拿出来,再用入队列函数(QueuePush)入到空队列,最后再用出队列函数(QueueFront)拿掉非空队列的最后一个 。
3:达到用队列实现栈的效果。
四:myStackTop函数(返回栈顶元素)
解释:
1:此函数目的是返回栈顶元素,根据前文两张图的对比,我们可知返回栈顶元素即返回队尾元素,直接用我们队列实现中的返回队尾函数(QueueBack)来实现。
五:myStackEmpty函数(判断栈是否空)
解释:
1:
两个队列都空了,就代表栈空。
六:myStackFree函数(销毁栈)
解释:
1:先销毁两个队列里的节点,再销毁obj
对于队列实现的双结构体的解释:
q1 ,q2它本质是Que,而在队列实现中Que是一个结构体,里面是头指针head,尾指针tail和size,只是随着节点增加,这两个指针指向队列里的节点,才能去控制队列,这就不用使用哨兵位了,所以并且q1,q2并不是一个队列。
为什么博主在代码中注释说的是队列呢?
因为不是所有人都是用的博主队列的实现(一篇包懂)-CSDN博客中的实现方法,所以博主注释写的模板化一点,才能尽力让不同的实现队列的方法的人,也能够理解。
所以具体的代码,需要根据自己的实现,来进行微调即可~~
本文思维导图: