用栈实现队列:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push
、pop
、peek
、empty
):
实现 MyQueue
类:
void push(int x)
将元素 x 推到队列的末尾int pop()
从队列的开头移除并返回元素int peek()
返回队列开头的元素boolean empty()
如果队列为空,返回true
;否则,返回false
1.题解:
通过两个栈的配合实现队列的基本功能,下面先实现栈的基本功能
栈: (前面文章介绍过栈的实现,这里就不过多阐述)
typedef int StackDataType;
typedef struct Stack {
StackDataType* head;
int capacity;
int size;
}Stack;
//创建栈
Stack* StackCreate() {
Stack* tmp = (Stack*)malloc(sizeof(Stack));
tmp->head = NULL;
tmp->capacity = tmp->size = 0;
return tmp;
}
//入栈
void StackPush(Stack*tmp,StackDataType x) {
if (tmp->capacity == tmp->size) {
int newcapacity = tmp->capacity == 0 ? 4 : 2 * tmp->capacity;
StackDataType* cur = (StackDataType*)realloc(tmp->head, newcapacity * sizeof(StackDataType));
if (cur == NULL) {
perror("StackPush:malloc");
exit;
}
tmp->head = cur;
tmp->capacity = newcapacity;
}
tmp->head[tmp->size] = x;
tmp->size++;
}
//出栈
StackDataType StackPop(Stack*tmp) {
if (tmp->size == 0) {
perror("StackPop:NULL");
exit;
}
StackDataType s = tmp->head[tmp->size - 1];
tmp->size--;
return s;
}
//栈的销毁
void StackDestroy(Stack*tmp) {
free(tmp->head);
tmp->head = NULL;
tmp->capacity = tmp->size = 0;
free(tmp);
tmp = NULL;
}
2.基于栈实现队列基本功能:
入队列:
根据上图思路,一个栈(stack1)存储数据,一个栈(stack2)出数据。
void myQueuePush(MyQueue* obj, int x) {
assert(obj);
StackPush(obj->stack1, x);
}
出队列:
出队列就涉及到判断出数据的那个栈(stack2)是否有数据(栈判空(StackEmpty))
int myQueuePop(MyQueue* obj) {
assert(obj);
if (obj->stack2->size == 0) {
while (obj->stack1->size != 0) {
StackPush(obj->stack2, StackPop(obj->stack1));
}
}
return StackPop(obj->stack2);
}
返回队列顶部元素:
同样涉及判空问题,因为该功能仅和出队列少了最后删除元素
int myQueuePeek(MyQueue* obj) {
assert(obj);
if (obj->stack2->size == 0) {
if (obj->stack1->size == 0) {
perror("Peek:NULL");
exit;
}
return obj->stack1->head[0];
}
return obj->stack2->head[obj->stack2->size - 1];
}
判空:
stack1与stack2均为空
bool myQueueEmpty(MyQueue* obj) {
assert(obj);
return obj->stack1->size == 0 && obj->stack2->size == 0;
}
3.完整代码:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int StackDataType;
typedef struct Stack {
StackDataType* head;
int capacity;
int size;
}Stack;
Stack* StackCreate() {
Stack* tmp = (Stack*)malloc(sizeof(Stack));
tmp->head = NULL;
tmp->capacity = tmp->size = 0;
return tmp;
}
void StackPush(Stack*tmp,StackDataType x) {
if (tmp->capacity == tmp->size) {
int newcapacity = tmp->capacity == 0 ? 4 : 2 * tmp->capacity;
StackDataType* cur = (StackDataType*)realloc(tmp->head, newcapacity * sizeof(StackDataType));
if (cur == NULL) {
perror("StackPush:malloc");
exit;
}
tmp->head = cur;
tmp->capacity = newcapacity;
}
tmp->head[tmp->size] = x;
tmp->size++;
}
StackDataType StackPop(Stack*tmp) {
if (tmp->size == 0) {
perror("StackPop:NULL");
exit;
}
StackDataType s = tmp->head[tmp->size - 1];
tmp->size--;
return s;
}
void StackDestroy(Stack*tmp) {
free(tmp->head);
tmp->head = NULL;
tmp->capacity = tmp->size = 0;
free(tmp);
tmp = NULL;
}
typedef struct Queue{
Stack* stack1;
Stack* stack2;
}MyQueue;
MyQueue* myQueueCreate() {
MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));
queue->stack1 = StackCreate();
queue->stack2 = StackCreate();
return queue;
}
void myQueuePush(MyQueue* obj, int x) {
assert(obj);
StackPush(obj->stack1, x);
}
int myQueuePop(MyQueue* obj) {
assert(obj);
if (obj->stack2->size == 0) {
while (obj->stack1->size != 0) {
StackPush(obj->stack2, StackPop(obj->stack1));
}
}
return StackPop(obj->stack2);
}
int myQueuePeek(MyQueue* obj) {
assert(obj);
if (obj->stack2->size == 0) {
if (obj->stack1->size == 0) {
perror("Peek:NULL");
exit;
}
return obj->stack1->head[0];
}
return obj->stack2->head[obj->stack2->size - 1];
}
bool myQueueEmpty(MyQueue* obj) {
assert(obj);
return obj->stack1->size == 0 && obj->stack2->size == 0;
}