数据结构-用栈模拟队列

利用两个栈S1、S2来模拟一个队列。

  • 利用两个栈S1和S2来模拟一个队列,当需要向队列中插入一个元素时,用s1来存放已输入的元素,即s1执行入栈操作。当需要出队时,则对s2执行出栈操作。由于从栈中取出元素的顺序是原顺序的逆序,所以必须先将S1中的所有元素全部出栈并入栈到S2中,再在S2中执行出栈操作,即可实现出队操作,而在执行此操作前必须判断S2是否为空,否则会导致顺序混乱。当栈S1和S2都为空时队列为空。
  • 总结如下:
  1. 对S2的出栈操作用作出队,若S2为空,则先将S1中的所有元素送入S2。
  2. 对S1的入栈操作用作入队,若S1满,必须先保证S2为空,才能将S1中的元素全部插入S2中。
    入 队 操 作 { 栈 s 1 未 满 — 可 以 继 续 入 栈 ( 即 可 以 继 续 入 队 ) 栈 s 1 已 满 { 栈 s 2 不 为 空 — 表 示 队 列 满 栈 s 2 为 空 — 将 栈 s 1 中 的 所 有 元 素 全 部 出 栈 , 并 入 栈 到 s 2 中 入队操作\begin{cases} 栈s1未满—可以继续入栈(即可以继续入队)\\ 栈s1已满 \begin{cases} 栈s2不为空—表示队列满\\ 栈s2为空—将栈s1中的所有元素全部出栈,并入栈到s2中 \end{cases}\\ \end{cases} s1()s1{s2s2s1s2
    出 队 操 作 { 栈 s 2 不 为 空 — 将 栈 s 2 中 的 所 有 元 素 全 部 出 栈 栈 s 1 、 s 2 都 为 空 — 表 示 队 列 空 栈 s 2 为 空 , 栈 s 1 不 为 空 — 将 栈 s 1 中 的 所 有 元 素 全 部 出 栈 , 并 入 栈 到 s 2 中 出队操作\begin{cases} 栈s2不为空—将栈s2中的所有元素全部出栈\\ 栈s1、s2都为空—表示队列空\\ 栈s2为空,栈s1不为空—将栈s1中的所有元素全部出栈,并入栈到s2中\\ \end{cases} s2s2s1s2s2s1s1s2
#include<iostream>
using namespace std;
#include<malloc.h>
#define MaxSize 10
typedef int ElemType;
typedef struct Stack
{
	ElemType data[MaxSize];
	int top;
};

void InitStack(Stack& s)
{ s.top = -1; }

bool StackEmpty(Stack s)
{
	return s.top == -1;
}

bool StackOverflow(Stack s)
{
	return s.top == MaxSize - 1;
}

bool Push(Stack& s, ElemType x)
{
	if (s.top == MaxSize - 1) return false;
	else
	{
		s.data[++s.top] = x;
		return true;
	}
}

bool Pop(Stack& s, ElemType& x)
{
	if (s.top == -1) return false;
	else x = s.data[s.top--];
	return true;
}

bool enQueue(Stack &s1,Stack &s2, ElemType x) //入队算法
{
	if(!StackOverflow(s1)) //栈s1未满
	{
		Push(s1, x); //入栈
		return true;
	}
	if (StackOverflow(s1) && !StackEmpty(s2)) //栈s1满,栈s2不为空
	{
		printf("队列满");
		return false;
	}
	if (StackOverflow(s1) && StackEmpty(s2)) //栈s1满,栈s2空
	{
		while (!StackEmpty(s1)) //将s1中所有的元素全部出栈并入栈到s2中,直到栈s1为空
		{
			Pop(s1, x); //s1元素出栈
			Push(s2, x); //s1中出栈元素入栈s2
		}
	}
	Push(s1, x); //栈s1未满时,继续入栈
	return true;
}

void deQueue(Stack &s1,Stack &s2,ElemType &x) //出队算法
{
	if (!StackEmpty(s2)) Pop(s2, x); //栈s2不为空时,s2中元素出栈
	else if (StackEmpty(s1)) cout << "队列为空" << endl; //栈s2为空且栈s1也为空,队列为空
	else //栈s2为空,栈s1不为空
	{
		while (!StackEmpty(s1)) //将s1中所有的元素全部出栈并入栈到s2中,直到栈s1为空
		{
			Pop(s1, x); //s1元素出栈
			Push(s2, x); //s1中出栈元素入栈s2
		}
	Pop(s2, x); //栈s2不为空时,继续出栈
	}
}

bool QueueEmpty(Stack s1,Stack s2) //判断队列为空算法
{ 
	if (StackEmpty(s1) && StackEmpty(s2)) return true; //栈s1、栈s1同时为空时,队列为空
	else return false;
}

int main()
{
	Stack s1,s2;
	InitStack(s1); InitStack(s2);
	int i;
	for (i = 1; i <= MaxSize; i++)
		enQueue(s1, s2, i); //需要入队时,先将元素入栈
	ElemType num;
	for (i = 0; i <= MaxSize-1; i++)
	{
		deQueue(s1, s2, num);
		cout << num << ' ';
	}	
	return 0;
}

程序分析:

在这里插入图片描述

  • 运行结果:
    在这里插入图片描述

利用两个队Q1、Q2来模拟一个栈。

初始入栈时,进入队列1,如果需要出队并且此时队列中只有一个元素时,可以直接出队;当队列中的元素个数多于1个时,此时需要反复将队列中除最后一个元素之外的所有元素入到另一个队列,每次只输出队列中的最后一个元素。

#include<iostream>
using namespace std;
#define MaxSize 10
typedef int ElemType;
typedef struct
{
	ElemType data[MaxSize];
	int front, rear;
}SqQueue;

void InitQueue(SqQueue& q)
{
	q.front = q.rear = 0; //初始化队首、队尾指针
}

bool QueueEmpty(SqQueue q)
{
	return q.rear == q.front;
}

bool QueueOverflow(SqQueue q)
{
	return  ((q.rear + 1) % MaxSize == q.front);
}

bool enQueue(SqQueue& q, ElemType e)
{
	if ((q.rear + 1) % MaxSize == q.front) return false; //队空则报错
	q.data[q.rear] = e;
	q.rear = (q.rear + 1) % MaxSize; //队尾指针加1取模
	return true;
}

bool deQueue(SqQueue& q, ElemType& e)
{
	if (q.rear == q.front) return false; //队满则报错
	e = q.data[q.front];
	q.front = (q.front + 1) % MaxSize; //队头指针加1取模
	return true;
}

bool Push(SqQueue &q1, SqQueue &q2,ElemType x) //队列模拟入栈操作
{
	if (!QueueOverflow(q1)&&QueueEmpty(q2)) //队列2为空时,将元素入栈到队列1
	{
		enQueue(q1, x);
		return true;
	}
	else if (!QueueOverflow(q2) && QueueEmpty(q1)) //队列1为空时,说明已经有奇数个元素进行了出栈操作
	{
		enQueue(q2, x);
		return true;
	}
	else if(QueueOverflow(q1) || QueueOverflow(q2)) //入栈操作必须保证有一个队列为空,否则操作时会导致数据混乱
	{
		printf("栈满,无法入栈!\n");
		return false;
	}
}

bool Pop(SqQueue &q1, SqQueue &q2,ElemType &x) //队列模拟出栈操作
{
	if (QueueEmpty(q1) && QueueEmpty(q2))
	{
		printf("栈空,无法出栈!\n");
		return false;
	}
	else
	{
		if (QueueEmpty(q2)) //队1不为空,队2为空,说明在此之前已经有偶数个元素出队
		{
			int num = (q1.rear - q1.front + MaxSize) % MaxSize; //队1中的总元素个数
			if (num > 1) //当队列中的元素个数多于1时
			{
				for (int i = 0; i < num-1; i++) //只留下最后一个元素,将前面的元素依次移到另一个队列中
				{
					deQueue(q1, x);
					enQueue(q2, x);
				}
				deQueue(q1, x); //输出最后一个元素
			}
			else deQueue(q1, x); //队列中只有一个元素时,直接出队
			return true;
		}
		else if (QueueEmpty(q1)) //队1为空,队2不为空,说明在此之前已经有奇数个元素出队
		{
			int num = (q2.rear - q2.front + MaxSize) % MaxSize; //队2中的总元素个数
			if (num > 1) //当队列中的元素个数多于1时
			{
				for (int j = 0; j < num-1; j++) //只留下最后一个元素,将前面的元素依次移到另一个队列中
				{
					deQueue(q2, x);
					enQueue(q1, x);
				}
				deQueue(q2, x); //输出最后一个元素
			}
			else deQueue(q2, x); //队列中只有一个元素时,直接出队
			return true;
		}
	}
}

int main()
{
	SqQueue q1,q2;
	int x,choose,num;
	InitQueue(q1); InitQueue(q2);
	while (choose)
	{
		printf("输入1(入栈)或2(出栈),输入0表示退出!\n");
		scanf("%d", &choose);
		switch (choose)
		{
		case 1:
			printf("请输入需要入栈的元素:");
			scanf("%d", &num);
			printf("入栈:%d\n", num);
			Push(q1, q2, num);
			break;
		case 2:
			if (QueueEmpty(q1) && QueueEmpty(q2)) printf("栈空,无法出栈!\n");
			else
			{
				Pop(q1, q2, x);
				printf("出栈元素为:%d\n", x);
			}
		}
	}
	return 0;
}

程序分析:

  • 运行结果:
    在这里插入图片描述
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值