一、分析问题
我们学完了栈和队列,也对这两个线性结构有了一定的了解,那么我们今天来看一看如何用栈实现队列的特性,先进先出呢?显然一个栈是完成不了的。
首先我们需要两个空栈,我们指定一个栈stack1当数据来的时候先入stack1,然后将栈stack1的元素依次弹出,弹出元素依次入栈stack2,然后在依次弹出stack2的元素就好了,但是细心的朋友有没有发现一个问题,如果我们弹出1、2,在3、4,没有弹出以前stack1又来了5、6,那怎么办?
所以我们要保证的是在有元素入栈stack1以前栈stack2是空的,也就是如果此时有元素要入栈stack1且栈stack2内有元素,要先将栈stack2内的元素全部压回栈stack1,stack2为空栈,再进行新元素入栈stack1的操作,同样道理在接下来对stack2进行Pop时也要保证stack1中的元素已经全部弹出压入stack2,也就是stack1是空栈。
二、代码实现分析
既然是用栈实现队列,那么就一定会用到我们之前学到的,对栈的一系列的操作代码。当然没用到那么多,那让我们看看需要我们新实现的部分,我们需要两个栈去充当一个队列,那么还需要一个队列计数器变量来实现监控队列里的元素个数,可以把这三个变量封装在一个结构体里面,还需要对我们的这个结构体进行初始化,说白了就是调用栈的初始化来对这个结构体里面的两个栈进行初始化,然后对队列的Push和Pop也要通过栈的Push和Pop重新完成。
三、代码实现
#include<stdio.h>
#include<stdlib.h>
typedef struct data
{
int nValue;
struct data *pNext;
}MyStack;
typedef struct stack
{
int nCount;
MyStack *pTop;
}Stack;
void s_Init(Stack **pStack)
{
*pStack = (Stack*)malloc(sizeof(Stack));
(*pStack)->nCount = 0;
(*pStack)->pTop = NULL;
}
void s_Push(Stack *pStack,int nNum)
{
if(pStack == NULL)
{
printf("不存在\n");
return;
}
MyStack *pTemp = NULL;
pTemp = (MyStack*)malloc(sizeof(MyStack));
pTemp->nValue = nNum;
pTemp->pNext = pStack->pTop;
pStack->pTop = pTemp;
pStack->nCount ++;
}
int s_Pop(Stack *pStack)
{
if(pStack == NULL) exit(1);
if(pStack->pTop == NULL) return -1;
MyStack *pDel = pStack->pTop;
int nNum = pDel->nValue;
pStack->pTop = pStack->pTop->pNext;
free(pDel);
pDel = NULL;
pStack->nCount --;
return nNum;
}
int s_IsEmpty(Stack *pSatck)
{
if(pSatck == NULL) exit(1);
return pSatck->nCount ? 0:1;
}
//以下是新代码
typedef struct queue
{
int nCount;
Stack *pStack1;
Stack *pStack2;
}Queue;
void q_Init(Queue **pQueue)
{
*pQueue = (Queue *)malloc(sizeof(Queue));
(*pQueue)->nCount = 0;
s_Init(&(*pQueue)->pStack1);
s_Init(&(*pQueue)->pStack2);
}
void q_Push(Queue *pQueue,int nNum)
{
if(pQueue == NULL) exit(1);
//栈1入队
//栈2非空 将栈2元素放回栈1 在向栈1压入
while(!s_IsEmpty(pQueue->pStack2))
{
s_Push(pQueue->pStack1,s_Pop(pQueue->pStack2));
}
s_Push(pQueue->pStack1,nNum);
pQueue->nCount ++;
}
int q_Pop(Queue *pQueue)
{
if(pQueue == NULL) exit(1);
if(pQueue ->nCount==0) return -1;
//栈2出队
//栈1非空 将栈1元素压入栈2 栈2弹出
while(!s_IsEmpty(pQueue->pStack1))
{
s_Push(pQueue->pStack2,s_Pop(pQueue->pStack1));
}
int nNum = s_Pop(pQueue->pStack2);
pQueue->nCount --;
return nNum;
}
int main()
{
Queue *pQueue = NULL;
q_Init(&pQueue);
q_Push(pQueue,1);
q_Push(pQueue,2);
q_Push(pQueue,3);
q_Push(pQueue,4);
printf("%d\n",q_Pop(pQueue));
printf("%d\n",q_Pop(pQueue));
q_Push(pQueue,5);
printf("%d\n",q_Pop(pQueue));
q_Push(pQueue,6);
printf("%d\n",q_Pop(pQueue));
printf("%d\n",q_Pop(pQueue));
printf("%d\n",q_Pop(pQueue));
return 0;
}