首先,我们比较一下栈和队列的特点:
- 栈的特点
- 只允许在固定的一端(栈顶)进行插入和删除元素操作;
- 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底;
- 栈中的数据元素遵守后进先出 LIFO(Last In First Out)的原则;
- 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶;
- 出栈:栈的删除操作叫做出栈,出数据也在栈顶;
- 队列的特点
- 只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表;
- 队列中的数据元素遵守先进先出 FIFO(First In First Out)的原则;
- 入队列:进行插入操作的一端称为队尾;
- 出队列:进行删除操作的一端称为队头;
实现
在实现过程中关键就是用出入栈模拟出入队列的过程:
- 入队列:
用栈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)