用栈实现队列
首先要了解的是栈和队列两种数据结构的特点。
栈:先进后出。队列:先进先出。
用栈实现队列(看下图):
如上图中所示,栈1开始进栈顺序为 1 2 3 4,依照栈的特点知道其出栈顺序为:4 3 2 1 。而若对一个队列入队顺序为:1 2 3 4则其出队顺序为:1 2 3 4。而图中所示,通过两个栈的一系列操作,使最终出数据的顺序为 1 2 3 4,与如数据的顺序相同,符合先进先出的特点。因而就可以看出,我们用两个栈就可以实现一个队列的特性,也就是说我们可以通过栈实现一个队列。
主要思想:构建两个栈,一个用来进数据(即图中栈1),一个人用来出数据(即栈2),进数据始终在栈1进行,出数据始终在栈2。
出栈:当栈2为空时,则应将栈1的数据进行出入栈操作,转移到栈2,再对栈2进行出栈操作。这样就可以之中保持数据的先进先出这一特性。(如图中所示)
入栈:入栈始终在栈1。
判断所实现的队列是否为空:两个栈都为空时,则队列为空,否则为非空。
具体代码实现如下:
首先需要的是构建栈,并实现栈的基本操作。代码如下:
#include<malloc.h>
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>
typedef int Datatype;
typedef struct Stack
{
Datatype* data;
int top;
int capcity;
}Stack;
void StackInit(Stack* st)//初始化栈
{
assert(st);
st->capcity = 10;
st->top = 0;
st->data = (Datatype*)malloc(sizeof(Stack));
}
void StackDestory(Stack* st)//销毁栈
{
assert(st);
st->top = 0;
st->capcity = 0;
free(st->data);
}
int StackEmpty(Stack* st)//判断栈是否为空
{
assert(st);
if (st->top == 0)
return 0;
else
return 1;
}
void StackPush(Stack* st, Datatype x)//入栈操作
{
assert(st);
if (st->top == st->capcity)
{
st->capcity *= 2;
st->data=realloc(st->data, sizeof(Datatype)*st->capcity);
}
st->data[st->top] = x;
st->top++;
}
void StackPop(Stack* st)//出栈
{
assert(st);
if (StackEmpty(st) == 0)
return;
else
st->top--;
}
int StackTop(Stack* st)//返回栈顶元素
{
assert(st&&st->top > 0);
return st->data[st->top - 1];
}
int StackSize(Stack* st)//栈中数据个数
{
if (StackEmpty(st) == 0)
return 0;
return st->top;
}
紧接着是用两个栈来实现一个队列:代码如下:
#include"Stack.h"
typedef struct MyQueue
{
Stack pushst;
Stack popst;
}MyQueue;
MyQueue* MyQueueInit()//初始化一个队列
{
MyQueue* pq = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&pq->pushst);
StackInit(&pq->popst);
return pq;
}
void MyQueueDestory(MyQueue* pq)//销毁一个队列
{
assert(pq);
StackDestory(&pq->popst);
StackDestory(&pq->pushst);
free(pq);
}
void MyQueuePush(MyQueue* pq, Datatype x)//入队操作
{
assert(pq);
StackPush(&pq->pushst, x);
}
void MyQueuePop(MyQueue* pq)//出队操作
{
assert(pq&&MyQueueEmpty(pq) != 0);
if (StackEmpty(&pq->popst) != 0)
StackPop(&pq->popst);
else
{
while (StackEmpty(&pq->pushst) != 0)
{
StackPush(&pq->popst, StackTop(&pq->pushst));
StackPop(&pq->pushst);
}
StackPop(&pq->popst);
}
}
int MyQueueEmpty(MyQueue* pq)//判断队是否为空
{
if (StackEmpty(&pq->popst) == 0 && StackEmpty(&pq->pushst) == 0)
return 0;
return 1;
}
int MyQueueLength(MyQueue* pq)//计算并返回队列的长度
{
assert(pq);
return StackSize(&pq->popst) + StackSize(&pq->pushst);
}
Datatype MyQueueFront(MyQueue* pq)//返回队头数据
{
assert(pq&&MyQueueEmpty(pq)!=0);
if (StackEmpty(&pq->popst) != 0)
return StackTop(&pq->popst);
else
{
while (StackEmpty(&pq->pushst) != 0)
{
StackPush(&pq->popst, StackTop(&pq->pushst));
StackPop(&pq->pushst);
}
return StackTop(&pq->popst);
}
}
int main()
{
MyQueue* pq = MyQueueInit();
MyQueuePush(pq, 1);
MyQueuePush(pq, 2);
MyQueuePush(pq, 3);
printf("Empty:%d\n",MyQueueEmpty(pq));//判空操作:0为空 1为非空
printf("length:%d\n", MyQueueLength(pq));//队列的长度
printf("Front:%d\n", MyQueueFront(pq));//队头数据
MyQueuePop(pq);//出队操作
MyQueuePop(pq);
MyQueuePop(pq);
MyQueueDestory(pq);
system("pause");
return 0;
}
以上就是栈的构建以及基本操作,以及用栈实现队列的过程,希望能帮助到大家。