Bootstrap

力扣225:用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

  • 你只能使用队列的标准操作 —— 也就是 push to backpeek/pop from frontsize 和 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);
*/

;