版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/qq_42719751/article/details/87869657
首先,我们比较一下栈和队列的特点:
- 栈的特点
- 只允许在固定的一端(栈顶)进行插入和删除元素操作;
- 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底;
- 栈中的数据元素遵守后进先出 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);
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