两个队列实现一个栈

栈是先进后出,队列是先进先出。把一个队列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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值