题目来源:力扣
题目描述:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
示例 1:
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
代码:
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* ps);
void STDestroy(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
int STSize(ST* ps);
bool STEmpty(ST* ps);
STDataType STTop(ST* ps);
void STInit(ST* ps) {
assert(ps);
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL) {
perror("malloc fail");
return;
}
ps->capacity = 4;
ps->top = 0; //给0代表栈顶元素的下一个
//ps->top = -1;//给-1代表栈顶元素的位置
}
void STDestroy(ST* ps) {
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void STPush(ST* ps, STDataType x) {
assert(ps);
if (ps->top == ps->capacity) {
STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType)*ps->capacity*2);
if (ps->a == NULL) {
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
void STPop(ST* ps) {
assert(ps);
assert(!STEmpty(ps));
ps->top--;
}
int STSize(ST* ps) {
assert(ps);
return ps->top;
}
bool STEmpty(ST* ps) {
assert(ps);
return ps->top == 0;
}
STDataType STTop(ST* ps) {
assert(ps);
assert(!STEmpty(ps));
return ps->a[ps->top-1];
}
typedef struct {
ST pushst;
ST popst;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* queue=(MyQueue*)malloc(sizeof(MyQueue));
if(queue==NULL){
perror("malloc fail");
}
STInit(&queue->pushst);
STInit(&queue->popst);
return queue;
}
void myQueuePush(MyQueue* obj, int x) {
STPush(&obj->pushst,x);
}
int myQueuePop(MyQueue* obj) {
if(STEmpty(&obj->popst)){
while(!STEmpty(&obj->pushst)){
STPush(&obj->popst,STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
int ret=STTop(&obj->popst);
STPop(&obj->popst);
return ret;
}
int myQueuePeek(MyQueue* obj) {
if(STEmpty(&obj->popst)){
while(!STEmpty(&obj->pushst)){
STPush(&obj->popst,STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
int ret = STTop(&obj->popst);
return ret;
}
bool myQueueEmpty(MyQueue* obj) {
bool ret=false;
if(STEmpty(&obj->popst)&&STEmpty(&obj->pushst)){
ret=true;
}
return ret;
}
void myQueueFree(MyQueue* obj) {
STDestroy(&obj->popst);
STDestroy(&obj->pushst);
free(obj);
}
思路:由于是使用c语言完成,所以我们先要写一个栈,写栈的博客我放在下面,大家可以去看看
有了栈后,我们就可以开始完成代码,队列的特点是先进先出,那我们使用两个栈,一个栈只入数据,一个栈只出数据,我们举个例子,入【1,2,3,4】后,无论队列怎么入数据,出队列的数据也一定是【1,2,3,4】,我们将数据入到一个栈后,如果此时出栈,顺序为【4,3,2,1】。但我们将数据全部转移到另一个栈里,就又变成了【1,2,3,4】,此时我们就可以放心出数据了,但是转移时,只有当出数据的栈为空才能将入数据的栈的数据进行转移,否则顺序会发生变化