请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现 MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回true
;否则,返回false
。
注意:
- 你只能使用队列的标准操作 —— 也就是
push to back
、peek/pop from front
、size
和is empty
这些操作。 - 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入: ["MyStack", "push", "push", "top", "pop", "empty"] [[], [1], [2], [], [], []] 输出: [null, null, null, 2, 2, false] 解释: MyStack myStack = new MyStack(); myStack.push(1); myStack.push(2); myStack.top(); // 返回 2 myStack.pop(); // 返回 2 myStack.empty(); // 返回 False
代码:
#define LEN 20
//队列操作
typedef struct queue{
int *data;//队列中的元素数组
int head;// 队列中的头
int rear;//队列中的尾
int size;//队列中元素的数量
}Queue;
typedef struct {//栈:用栈实现队列的操作
Queue *queue1,*queue2;
}MyStack;
Queue *initQueue(int k){//初始化队列
Queue *obj = (Queue*)malloc(sizeof(Queue));//创建一个新的队列:开辟空间
obj -> data = (int*)malloc(sizeof(int)*k);//数组进行malloc
obj -> head = -1;//数组的头为-1
obj -> rear = -1;//数组的尾为-1
obj -> size = k;//数组的大小为k
return obj;
}
void enQueue(Queue *obj,int k){//在队列中插入一个新元素(插入在对尾)
if(obj -> head == -1){
//head为头指针,保存第一个元素的下标,这时考虑队列为空的情况
obj -> head = 0;//改变头指针的位置
}
obj -> rear = (obj -> rear + 1) % (obj -> size);//改变尾指针的位置
obj -> data[obj -> rear] = k;//插入元素
//注意由于尾指针由于是最后一个元素的位置,故尾指针应该先移动再插入元素
}
int delQueue(Queue *obj){//删除队列中的元素(删除队头元素)
int num = obj -> data[obj -> head];//保存队头元素的值
//一旦删除队头元素,就会移动指针,一旦移动指针,就找不到队头元素
if(obj -> head == obj -> rear){//队列中只有一个元素的情况(删除后就没有元素)
obj -> head = -1;
obj -> rear = -1;
return num;
}
obj -> head = (obj -> head + 1)%(obj -> size);//改变头指针的位置
return num;
}
int isempty(Queue *obj){//对队列中的元素判空
return obj -> head == -1;
}
MyStack* myStackCreate() {
//创建一个栈,一个栈是由两个队列组成的,一个是主队列,一个是辅助队列
MyStack *obj = (MyStack*)malloc(sizeof(MyStack));
obj -> queue1 = initQueue(LEN);
obj -> queue2 = initQueue(LEN);
return obj;
}
void myStackPush(MyStack* obj, int x) {//压栈
//谁不空,就将元素压入谁(插入到哪个队列)
if(isempty(obj -> queue1)){
enQueue(obj -> queue2,x);
}
else{
enQueue(obj -> queue1,x);
}
}
int myStackPop(MyStack* obj) {
//pop操作是要删除队尾的元素,就是把一个队列依次出队并把元素依次入队到另一个队列,直至队列中只有一个元素
if(isempty(obj -> queue1)){//队列1空,2不空
while(obj -> queue2 -> head != obj -> queue2 -> rear){
//队列中的元素大于1
enQueue(obj -> queue1, delQueue(obj -> queue2));
}
return delQueue(obj -> queue2);
}
//队列2空,1不空
while(obj -> queue1 -> head != obj -> queue1 -> rear){
//队列中的元素大于1
enQueue(obj -> queue2,delQueue(obj -> queue1));
}
return delQueue(obj -> queue1);
}
int myStackTop(MyStack* obj) {//返回栈顶元素(返回队尾元素)
if(isempty(obj -> queue1)){
return obj -> queue2 -> data[obj -> queue2 ->rear];
}
return obj -> queue1 -> data[obj -> queue1 -> rear];
}
bool myStackEmpty(MyStack* obj) {//判断栈是否为空
if(obj -> queue1 -> head == -1 && obj -> queue2 -> head == -1){
return true;
}
return false;
}
void myStackFree(MyStack* obj) {//释放队列
free(obj -> queue1 -> data);
obj -> queue1 -> data = NULL;
free(obj -> queue1);
obj -> queue1 = NULL;
free(obj -> queue2 -> data);
obj -> queue2 -> data = NULL;
free(obj -> queue2);
obj -> queue2 = NULL;
free(obj);
obj = NULL;
}
/**
* Your MyStack struct will be instantiated and called as such:
* MyStack* obj = myStackCreate();
* myStackPush(obj, x);
* int param_2 = myStackPop(obj);
* int param_3 = myStackTop(obj);
* bool param_4 = myStackEmpty(obj);
* myStackFree(obj);
*/