两个队列实现一个栈

本文介绍如何利用两个顺序队列来模拟栈的数据结构。详细讲述了主要思想、结构设计以及包括初始化、入栈、获取栈顶元素、删除栈顶元素、判空、判满、获取元素个数、清空和销毁在内的基本操作。通过这种方式,可以借助队列的特性完成栈的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.主要思想

栈的特点:先进后出。队列的特点:先进先出。
我们在用两个队列实现栈的时候是用顺序队列。
在这里插入图片描述

2.结构设计

既然是用两个队列实现栈的操作,所以定义的结构体中的成员就是两个队列。

typedef struct
{
	SqQueue q1;
	SqQueue q2;
}TQStack, *PTQStack;

3.基本操作

  1. 我们要实现的是一个栈,所以所有的操作都是基于栈的基础上,栈有什么操作,我们实现的就有什么操作。
  2. 我们用两个队列实现栈的操作中,队列的所有操作是给定的,在我们实现栈的过程中,只需要调用其函数即可(见顺序队列)。

(1)初始化

void my_InitStack(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return;

	Init_Queue(&ptq->q1);
	Init_Queue(&ptq->q2);
}

(2)入栈

哪个队列不空就入哪个队列。

bool my_Push(PTQStack ptq, int val)
{
	assert(ptq != NULL);
	if (ptq == NULL)return false;

	if (!IsEmpty(&ptq->q1))
	{
		return Push(&ptq->q1,val);
	}
	else
	{
		return Push(&ptq->q2, val);
	}
}

(3)获取栈顶第一个元素的值,但不删除

栈顶的元素就是队列尾的元素,要将队列尾部的元素得到,就需要将其他元素一次存放进另一个队列中保存。

bool my_GetTop(PTQStack ptq, int* rtval)
{
	assert(ptq != NULL && rtval != NULL);
	if (ptq == NULL || rtval == NULL)return false;

	if (!IsEmpty(&ptq->q1))//如果q1不空,就将q1中的元素只留一个,其他的都存入q2中。最后一个数就是栈顶元素;
	{
		while (Get_length(&ptq->q1) > 1)
		{
			int tmp = 0;
			Pop(&ptq->q1, &tmp);
			Push(&ptq->q2, tmp);
		}
		return Get_top(&ptq->q1, rtval);
	}
	else
	{
		while (Get_length(&ptq->q2) > 1)
		{
			int tmp = 0;
			Pop(&ptq->q2, &tmp);
			Push(&ptq->q1, tmp);
		}
		return Get_top(&ptq->q2, rtval);
	}
}

(4)获取栈顶第一个元素的值并删除

bool my_Pop(PTQStack ptq, int* rtval)
{
	assert(ptq != NULL && rtval != NULL);
	if (ptq == NULL || rtval == NULL)return false;

	if (!IsEmpty(&ptq->q1))
	{
		while (Get_length(&ptq->q1) > 1)
		{
			int tmp = 0;
			Pop(&ptq->q1, &tmp);
			Push(&ptq->q2, tmp);
		}
		return Pop(&ptq->q1, rtval);
	}
	else
	{
		while (Get_length(&ptq->q2) > 1)
		{
			int tmp = 0;
			Pop(&ptq->q2, &tmp);
			Push(&ptq->q1, tmp);
		}
		return Pop(&ptq->q2, rtval);
	}
}

(5)判空

bool my_IsEmpty(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return false;
	
	return IsEmpty(&ptq->q2)&& IsEmpty(&ptq->q1);
}

(6)判满

我们在入队是时,是向栈1中入的,如果栈1满了,再向栈2中入就堵住下一个要出的元素了,所以在判满时,只需要判断栈1满不满即可。

bool my_IsFull(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return false;

	if (!IsEmpty(&ptq->q1))
	{
		return(IsFull(&ptq->q1));
	}
	else
	{
		return(IsFull(&ptq->q2));
	}
}

(7)获取队列有效元素个数

int my_Get_length(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return -1;

	if (!IsEmpty(&ptq->q1)) 
	{ 
		return Get_length(&ptq->q1);
	}
	return Get_length(&ptq->q2);
}

(8)清空

void my_Clear(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return;

	Clear(&ptq->q2);
	Clear(&ptq->q1);
}

(9)销毁

void my_Destroy(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return;

	Destroy(&ptq->q2);
	Destroy(&ptq->q1);
}

4.完整代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef struct
{
	SqQueue q1;
	SqQueue q2;
}TQStack, *PTQStack;

void my_InitStack(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return;

	Init_Queue(&ptq->q1);
	Init_Queue(&ptq->q2);
}

//入栈
bool my_Push(PTQStack ptq, int val)
{
	assert(ptq != NULL);
	if (ptq == NULL)return false;

	if (!IsEmpty(&ptq->q1))
	{
		return Push(&ptq->q1,val);
	}
	else
	{
		return Push(&ptq->q2, val);
	}
}

//判满
bool my_IsFull(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return false;

	if (!IsEmpty(&ptq->q1))
	{
		return(IsFull(&ptq->q1));
	}
	else
	{
		return(IsFull(&ptq->q2));
	}
}

//判空
bool my_IsEmpty(PTQStack ptq)
{
	return IsEmpty(&ptq->q2)&& IsEmpty(&ptq->q1);
}

//获取栈首的值
bool my_GetTop(PTQStack ptq, int* rtval)
{
	assert(ptq != NULL && rtval != NULL);
	if (ptq == NULL || rtval == NULL)return false;

	if (!IsEmpty(&ptq->q1))
	{
		while (Get_length(&ptq->q1) > 1)
		{
			int tmp = 0;
			Pop(&ptq->q1, &tmp);
			Push(&ptq->q2, tmp);
		}
		return Get_top(&ptq->q1, rtval);
	}
	else
	{
		while (Get_length(&ptq->q2) > 1)
		{
			int tmp = 0;
			Pop(&ptq->q2, &tmp);
			Push(&ptq->q1, tmp);
		}
		return Get_top(&ptq->q2, rtval);
	}
}

//出栈
bool my_Pop(PTQStack ptq, int* rtval)
{
	assert(ptq != NULL && rtval != NULL);
	if (ptq == NULL || rtval == NULL)return false;

	if (!IsEmpty(&ptq->q1))
	{
		while (Get_length(&ptq->q1) > 1)
		{
			int tmp = 0;
			Pop(&ptq->q1, &tmp);
			Push(&ptq->q2, tmp);
		}
		return Pop(&ptq->q1, rtval);
	}
	else
	{
		while (Get_length(&ptq->q2) > 1)
		{
			int tmp = 0;
			Pop(&ptq->q2, &tmp);
			Push(&ptq->q1, tmp);
		}
		return Pop(&ptq->q2, rtval);
	}
}

//获取有效长度
int my_Get_length(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return -1;

	if (!IsEmpty(&ptq->q1)) 
	{ 
		return Get_length(&ptq->q1);
	}
	return Get_length(&ptq->q2);
}

//清空
void my_Clear(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return;

	Clear(&ptq->q2);
	Clear(&ptq->q1);
}

//销毁
void my_Destroy(PTQStack ptq)
{
	assert(ptq != NULL);
	if (ptq == NULL)return;

	Destroy(&ptq->q2);
	Destroy(&ptq->q1);
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值