栈是先进后出,队列是先进先出。把一个队列q1当作存数据的队列,另一个队列q2当作替换队列就可以实现一个栈。
具体方法:当进栈的时候,就直接给存数据的队列进去。当要出栈的时候,因为要出队尾,所以我们把q1队列的前n-1个元素一个个出队q1,入队到q2里去,剩下一个元素就是要出栈的元素,然后直接出队就完成了出栈操作。然后下一次就吧q1和q2反过来就好了,具体代码实现如下,要注意处理好怎么判断从哪个队列移动到哪个队列就可以了。
代码:(C语言实现)
头文件queue.h:这里是队列的一些方法,具体队列的实现请查看:C语言实现队列
#define _CRT_SECURE_NO_WARNINGS 1
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define length 10
typedef int DataType;
typedef struct QueueNode
{
DataType _data;
struct QueueNode* _next;
}QueueNode;
typedef struct Queue
{
QueueNode* _head;
QueueNode* _tail;
}Queue;
void QueueInit(Queue* q);//初始化
void QueuePush(Queue* q, DataType x);//加入
void QueuePop(Queue* q);//弹出
DataType QueueFront(Queue* q);//看头
DataType QueueBack(Queue* q);//看尾
int QueueSize(Queue* q);//看大小
int QueueEmpty(Queue* q);//判空
两个队列实现一个栈:
#include "queue.h"
typedef struct stack
{
Queue q1;
Queue q2;
DataType* top;//栈顶指针
}stack;
//栈初始化
void sInit(stack* s)
{
assert(s);
QueueInit(&(s->q1));
QueueInit(&(s->q2));
}
//入栈
void sPush(stack* s, DataType value)
{
assert(s);
if (QueueEmpty( &(s->q1) ) ) //如果q1是空的,往q2里入,一开始往q2里面入栈
{
QueuePush(&(s->q2), value);
printf("入栈:%d\n", value);
}
else if (QueueEmpty(&(s->q2)))
{
QueuePush(&(s->q1), value);
printf("入栈:%d\n", value);
}
}
void movefunction(Queue* q1, Queue* q2)//吧q1的前n-1个复制到q2
{
int leng = QueueSize(q1);
//printf("leng = %d\n", leng);
for (int i = 0; i < leng - 1; i++)
{
//循环leng-1次
DataType tmp = QueueFront(q1);//取队头
QueuePop(q1);//q1弹出队头
QueuePush(q2, tmp);//q2放进队头
//printf("把%d放到另一个队列\n", tmp);
}
}
//出栈
void sPOP(stack* s)
{
assert(s);
if (QueueEmpty(&(s->q1))) //如果q1是空的,那就要吧q2的往q1里面存
{
movefunction(&(s->q2), &(s->q1));//把前n-1个复制到q1里
QueuePop(&(s->q2));//q2弹出最后一个(栈顶)
}
else if (QueueEmpty(&(s->q2)))
{
movefunction(&(s->q1), &(s->q2));
QueuePop(&(s->q1));//q2弹出最后一个(栈顶)
}
}
//查看栈顶
DataType sPeek(stack* s)
{
assert(s);
if (QueueEmpty(&(s->q1))) //如果q1是空的,那就要吧q2的往q1里面存
{
DataType tmp;
movefunction(&(s->q2), &(s->q1));//把前n-1个复制到q1里
tmp = QueueFront(&(s->q2));
QueuePop(&(s->q2));//q1弹出队头
QueuePush(&(s->q1), tmp);//q2放进队头//移动最后一个去q1
return tmp;
}
else if (QueueEmpty(&(s->q2)))
{
DataType tmp;
movefunction(&(s->q1), &(s->q2));//把前n-1个复制到q1里
tmp = QueueFront(&(s->q1));
QueuePop(&(s->q1));//q1弹出队头
QueuePush(&(s->q2), tmp);//q2放进队头//移动最后一个去q1
return tmp;
}
}
//查看大小
int sSize(stack* s)
{
assert(s);
if (QueueEmpty(&(s->q1))) //如果q1是空的,那就要吧q2的往q1里面存
{
return QueueSize(&(s->q2));
}
else if (QueueEmpty(&(s->q2)))
{
return QueueSize(&(s->q1));
}
}
int main()
{
stack s;
sInit(&s);
sPush(&s, 1);
sPush(&s, 2);
sPush(&s, 3);
sPush(&s, 4);
sPush(&s, 5);
printf("当前大小:%d\n", sSize(&s));
printf("弹出:%d\n", sPeek(&s));//弹出5
sPOP(&s);
printf("弹出:%d\n", sPeek(&s));//弹出4
sPOP(&s);
printf("弹出:%d\n", sPeek(&s));//弹出3
sPOP(&s);
printf("大小:%d\n", sSize(&s));//当前大小2
system("pause");
return 0;
}