用两个栈实现一个队列(C语言)

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/qq_42719751/article/details/87869657

首先,我们比较一下栈和队列的特点:

- 栈的特点

  1. 只允许在固定的一端(栈顶)进行插入和删除元素操作;
  2. 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底;
  3. 栈中的数据元素遵守后进先出 LIFO(Last In First Out)的原则;
  4. 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶;
  5. 出栈:栈的删除操作叫做出栈,出数据也在栈顶;

- 队列的特点

  1. 只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表;
  2. 队列中的数据元素遵守先进先出 FIFO(First In First Out)的原则;
  3. 入队列:进行插入操作的一端称为队尾;
  4. 出队列:进行删除操作的一端称为队头;

实现

在实现过程中关键就是用出入栈模拟出入队列的过程:

  • 入队列:
    用栈1(以下简称为:s1)一直作为入队列是的存储元素的部分,在入队列的时候栈2(以下简称为:s2)一直为空;
    入队列思路
    在这里插入图片描述
  • 出队列:
    出队列时出的是队列的队头元素,就是最先存进队列的元素。所以,出队列出队列时,先将s1的所有元素pop入s2中,再将s2的栈顶元素pop,此时,出队列基本完成,为了后续可能进行的Push等操作,还需要将s2中的元素pop入s1中,这样,出队列全部完成。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

以下为具体实现

Queue(Stack).h文件

//Queue(Stack).h
#pragma once //保证头文件只被编译一次
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define max_size 1000

typedef int Datatypedef;
typedef struct Stack
{
	Datatypedef _data[max_size];
	int _sizeStack; //栈中的元素个数
}Stack;  
typedef struct Queue
{
	Stack _s1;
	Stack _s2;
	Datatypedef _front; //队头
	Datatypedef _rear;  //队尾
	int _sizeQueue; //队列中的元素个数
}Queue;

void QueueInit(Queue* q); //队列初始化函数
void QueueDestroy(Queue* q); //队列销毁函数
void QueuePush(Queue* q,Datatypedef val); //入队列函数
void QueuePop(Queue* q); //出队列函数
Datatypedef QueueFront(Queue* q); //取队头元素函数
Datatypedef QueueRear(Queue* q); //取队尾元素函数
int QueueSize(Queue* q); //求队列元素个数

Queue(Stack).c文件

//Queue(Stack).c

//1.先将栈的结构实现
//栈的初始化函数
void StackInit(Stack* s)
{
	assert(s);
	if (s->_data == NULL)
		return;
	s->_sizeStack = 0;
}
//栈的销毁函数
void StackDestroy(Stack* s)
{
	assert(s);
	if (s->_data == NULL)
		return;
	s->_sizeStack = 0;
}
//入栈函数
void StackPush(Stack* s,Datatypedef val)
{
	assert(s);
	if (s->_data == NULL)
		return;
	if (s->_sizeStack == max_size)
		return;
	s->_data[s->_sizeStack] = val;
	s->_sizeStack++;
}
//出栈函数
void StackPop(Stack* s,Datatypedef* val)
{
	assert(s);
	if (s->_data == NULL)
		return;
	if (0 == s->_sizeStack)
		return;
	*val = s->_data[s->_sizeStack];
	s->_sizeStack--;
}
//取栈顶元素函数
Datatypedef StackTop(Stack* s)
{
	assert(s);
	if (s == NULL)
		return -1;
	if (0 == s->_sizeStack)
		return -1;
	return s->_data[s->_sizeStack-1];
}

//2.用两个栈实现队列
////队列初始化函数
void QueueInit(Queue* q)
{
	assert(q);
	if (q == NULL)
		return;
	StackInit(&q->_s1);
	StackInit(&q->_s2);
	q->_sizeQueue = 0;
	q->_front = 0;
	q->_rear = 0;
}
//队列销毁函数
void QueueDestroy(Queue* q)
{
	assert(q);
	if (q == NULL)
		return;
	StackDestroy(&q->_s1);
	StackDestroy(&q->_s2);
	q->_sizeQueue = 0;
	q->_front = 0;
	q->_rear = 0;
}
//入队列函数
void QueuePush(Queue* q, Datatypedef val)
{
	assert(q);
	if (q == NULL)
		return;

	//判断队列是否存满,当多于max_size时,无法pop
	if (q->_sizeQueue == max_size)
		return;
	//将插入的元素全部放入s1中
	StackPush(&q->_s1, val);
	q->_sizeQueue++;
}
//出队列函数
void QueuePop(Queue* q)
{
	assert(q);
	Datatypedef temp = 0;
	if (q == NULL)
		return;
	//判空
	if (0 == q->_sizeQueue)
		return;

	//pop时,将s1的元素放入s2中,再将s2的栈顶元素pop
	while (q->_s1._sizeStack)
	{
		StackPop(&q->_s1, &temp);
		StackPush(&q->_s2, temp);
	}
	StackPop(&q->_s2,&temp);
	while (q->_s2._sizeStack)
	{
		StackPop(&q->_s2, &temp);
		StackPush(&q->_s1, temp);
	}
	q->_sizeQueue--;
}
//取队头元素函数
Datatypedef QueueFront(Queue* q)
{
	assert(q);
	if (NULL == q)
		return -1;
	if (0 == q->_sizeQueue)
		return -1;
	q->_front = q->_s1._data[0];
	return (q->_front);
}
//取队尾元素函数
Datatypedef QueueRear(Queue* q)
{
	assert(q);
	if (q == NULL)
		return -1;
	//判空
	if (0 == q->_sizeQueue)
		return -1;
	return StackTop(&q->_s1);
}
//求队列元素个数
int QueueSize(Queue* q)
{
	assert(q);
	if (q == NULL)
		return -1;
	return q->_sizeQueue;
}

测试test.c文件

//test.c
#include"Queue(stack).h"
int main()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);
	QueuePush(&q, 6);
	printf("%d\n", QueueFront(&q));
	printf("%d\n", QueueRear(&q));
	printf("%d\n\n\n", QueueSize(&q));

	QueuePop(&q);
	printf("%d\n", QueueFront(&q));
	printf("%d\n", QueueRear(&q));
	printf("%d\n\n\n", QueueSize(&q));
	QueueDestroy(&q);
	system("pause");
	return 0;
}

Keep Running

猜你喜欢

转载自blog.csdn.net/qq_42719751/article/details/87869657
今日推荐