之前的几章我讲解了栈和队列的基本特性和一些基本的操作方法,那么如何能利用栈来实现队列呢?
下面我来讲解下具体思路,栈的特性先进后出,队列是先进先出,如果要模拟队列的这个特性,我们就必须用到两个栈。
一个栈用来入队,一个栈用来出队。什么意思呢?就是我们把数据存放到第一个栈中,再把里面的数据全部移动到第二个栈后在出栈,就能够模拟出队列的先进先出的特性
假设我们操作1 ,2,3,4这四个数据
如果是队列的话
入队后再全部出队
数据还是1, 2 ,3 ,4.
然后用两个栈实现
先将数据全放到入队栈中
然后将入队栈的所有数据放到出队栈里面
再将其出栈
就达到了我们的目的。
下面开始代码实现
数据结构
#define STACKSIZE 100
typedef int DataType;
typedef struct Stack
{
DataType* data;
int top; // 栈顶
int capacity; // 容量
}Stack;
typedef struct
{
Stack pops;
Stack pushs;
} MyQueue;
栈的实现部分就不再这里放了,之前几章有
初始化队列
MyQueue* myQueueCreate()
{
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&q->pushs);
StackInit(&q->pops);
return q;
}
入队列
void myQueuePush(MyQueue* obj, int x)
{
StackPush(&obj->pushs, x);
}
直接把数据放入入队栈中
出队列
int myQueuePop(MyQueue* obj)
{
if(StackEmpty(&obj->pops))
{
while(!StackEmpty(&obj->pushs))
{
StackPush( &obj->pops, StackTop(&obj->pushs));
StackPop(&obj->pushs);
}
}
int ret = StackTop(&obj->pops);
StackPop(&obj->pops);
return ret;
}
当出队栈为空时把入队栈所有数据放入出队栈中,然后直接弹出栈顶
获取队首元素
int myQueuePeek(MyQueue* obj)
{
int top;
if(StackEmpty(&obj->pops))
{
while(!StackEmpty(&obj->pushs))
{
StackPush( &obj->pops, StackTop(&obj->pushs));
StackPop(&obj->pushs);
}
}
top = StackTop(&obj->pops);
return top;
}
与出队思路相同
判断队列是否为空
bool myQueueEmpty(MyQueue* obj)
{
if(StackEmpty(&obj->pops) && StackEmpty(&obj->pushs))
return true;
else
return false;
}
判断两个栈是否同时为空,如果不是则队不为空
销毁队列
void myQueueFree(MyQueue* obj)
{
StackDestroy(&obj->pushs);
StackDestroy(&obj->pops);
free(obj);
}
这样我们就实现了用栈来实现队列,下一章讲解用队列实现栈
完整代码
#define STACKSIZE 100
typedef int DataType;
typedef struct Stack
{
DataType* data;
int top; // 栈顶
int capacity; // 容量
}Stack;
typedef struct {
Stack pops;
Stack pushs;
} MyQueue;
void ChackCapacity(Stack* ps)
{
if (ps->top >= ps->capacity)
{
ps->capacity *= 2;
ps->data = (DataType*)realloc(ps->data, ps->capacity * sizeof(DataType));
}
}
void StackInit(Stack* ps)
{
ps->data = (DataType*)malloc(STACKSIZE * sizeof(DataType));
ps->top = 0;
ps->capacity = STACKSIZE;
}
// 入栈
void StackPush(Stack* ps, DataType data)
{
ChackCapacity(ps);
ps->data[ps->top++] = data;
}
// 出栈
void StackPop(Stack* ps)
{
if (0 == ps->top)
return;
ps->top--;
}
// 获取栈顶元素
DataType StackTop(Stack* ps)
{
if (0 == ps->top)
return (DataType)0;
return ps->data[ps->top - 1];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps)
{
return ps->top;
}
// 检测栈是否为空,如果为空返回非零(1),如果不为空返回0
int StackEmpty(Stack* ps)
{
return ps->top == 0;
}
// 销毁栈
void StackDestroy(Stack* ps)
{
free(ps->data);
ps->data = NULL;
ps->top = 0;
ps->capacity = 0;
}
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&q->pushs);
StackInit(&q->pops);
return q;
}
void myQueuePush(MyQueue* obj, int x)
{
StackPush(&obj->pushs, x);
}
int myQueuePop(MyQueue* obj)
{
if(StackEmpty(&obj->pops))
{
while(!StackEmpty(&obj->pushs))
{
StackPush( &obj->pops, StackTop(&obj->pushs));
StackPop(&obj->pushs);
}
}
int ret = StackTop(&obj->pops);
StackPop(&obj->pops);
return ret;
}
/** Get the front element. */
int myQueuePeek(MyQueue* obj)
{
int top;
if(StackEmpty(&obj->pops))
{
while(!StackEmpty(&obj->pushs))
{
StackPush( &obj->pops, StackTop(&obj->pushs));
StackPop(&obj->pushs);
}
}
top = StackTop(&obj->pops);
return top;
}
bool myQueueEmpty(MyQueue* obj)
{
if(StackEmpty(&obj->pops) && StackEmpty(&obj->pushs))
return true;
else
return false;
}
void myQueueFree(MyQueue* obj)
{
StackDestroy(&obj->pushs);
StackDestroy(&obj->pops);
free(obj);
}