前言:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
目录
1.栈得实现
1.1结构体定义
1.2初始化栈
1.3压栈函数
1.4出栈函数
1.5返回栈顶函数
1.6判空函数
1.7销毁函数
2.题目解析
3.软件程序
3.1结构体定义及初始化
3.2进队函数
3.3出队函数
3.3返回队头元素
3.4判空函数
3.5销毁函数
1.栈得实现
这个题我是使用C语言解法进行解题得,因为要使用栈实现队列,所以首先我们要有栈得源函数,我在这里就把之前写过得栈得源函数按功能分类拷贝下来:代码如下:
1.1结构体定义
typedef int STDataType;
typedef struct Stack
{
STDataType* a;//数组栈
int top;//栈顶
int capacity;//容量
}ST;
1.2初始化栈
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0; // ps->top = -1;
ps->capacity = 0;
}
1.3压栈函数
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
1.4出栈函数
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
1.5返回栈顶函数
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
1.6判空函数
bool StackEmpty(ST* ps)
{
assert(ps);
/*if (ps->top == 0)
{
return true;
}
else
{
return false;
}*/
return ps->top == 0;
}
1.7销毁函数
bool StackEmpty(ST* ps)
{
assert(ps);
/*if (ps->top == 0)
{
return true;
}
else
{
return false;
}*/
return ps->top == 0;
}
2.题目解析
我们知道队列是先进先出得,数据得进出如下图所示:
而栈得数据是先进后出, 如果上面数据进入栈内,先出的肯定就是数据6,不符合队列要求的数字1先出,所以我们要使用两个栈,一个栈pushST用来将所有数据存储进去,另一个栈popST用来出数据,这样就会把栈底得数据,在出数据得得栈中第一个出去,就满足队列得先进先出得原则。图解图下:
我们如果这时候想入数据,应该往pushST这个栈里面入,出数据就看popST栈中有无数据,没有数据就往里添pushST中得数据,如果有直接出,如下图所示:
3.软件程序
3.1结构体定义及初始化
typedef struct {
ST pushST; //定义一个专门存数据得栈
ST popST;//定义一个专门出数据得栈
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue *q = (MyQueue*)malloc(sizeof(MyQueue)); //定义一个结构体指针变量 指向两个栈
StackInit(&q->pushST);//初始化
StackInit(&q->popST);
return q;
}
3.2进队函数
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->pushST,x); // 开始存数据
}
3.3出队函数
要先判断栈里面是否为空,为空要先进数据。题目要求 要返回出队得元素,所以我们要定义个变量用来存储出队得数据,代码如下:
int myQueuePop(MyQueue* obj) {
//如果出栈得数据为空得话,要将存数据得栈内数据放进出栈
if(StackEmpty(&obj->popST))
{
while(!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST,StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
int front = StackTop(&obj->popST);
StackPop(&obj->popST);
return front;
}
3.3返回队头元素
返回的队头元素即为,出栈得栈定元素,代码如下:
int myQueuePeek(MyQueue* obj) {
if(StackEmpty(&obj->popST))
{
while(!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST,StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
//返回栈定数据
return StackTop(&obj->popST);
}
3.4判空函数
如果pushST栈 以及popST栈都为空得话 则队列为空,直接用表达式真假判断即可,代码如下:
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
}
3.5销毁函数
我们需要先销毁两个栈,再销毁 自定义结构体指针变量得指向,图解如下:
代码如下:
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->pushST);
StackDestroy(&obj->popST);
free(obj);
}