漫画:如何用栈实现队列



队列的特点是先入先出,出入元素是在不同的两端(队头和队尾),而栈的特点是先入后出,出入元素都是在同一端(栈顶)。

下图就是一个典型的队列的结构。需要加入队列中的元素是往队尾添加的,而需要出队的元素从队头出。


在栈中有一个指针Top,永远指向栈顶元素,如果栈为空,那么Top就为nil。在栈结构中无论是入栈还是出栈,都是操作栈顶元素。所以入栈顺序与出栈顺序是相反的。

既然我们拥有两个队列,那么我们可以让其中一个栈作为队列的入口,负责插入新元素;另一个栈作为队列的出口,负责移除老元素。

原理说明

由于栈只能操作一端,因此我们peek或者pop的时候也只去操作栈顶元素,要达到目的我们需要在push的时候将队头的元素放到栈顶即可。具体做法是先将栈依次pop并push至另一个辅助栈中,最后将新的元素push到辅助栈顶,然后再将辅助栈中的元素依次pop放回原栈中。

比如我们现在栈中已经是1,2,3,4了。我们现在要push一个5.

push之前是这样的:

然后我们将栈中的元素转移到辅助栈,最后将新的元素添加到栈顶。

然后再将辅助栈中的元素依次pop放回原栈中。

整个过程是这样的:

image

出队的时候,显然只要对stack执行pop操作即可



/*
 * @lc app=leetcode id=232 lang=javascript
 *
 * [232] Implement Queue using Stacks
 */
/**
 * Initialize your data structure here.
 */
var MyQueue = function() {
  // tag: queue stack array
  this.stack = [];
  this.helperStack = [];
};

/**
 * Push element x to the back of queue.
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function(x) {
  let cur = null;
  while ((cur = this.stack.pop())) {
    this.helperStack.push(cur);
  }
  this.helperStack.push(x);

  while ((cur = this.helperStack.pop())) {
    this.stack.push(cur);
  }
};

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function() {
  return this.stack.pop();
};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function() {
  return this.stack[this.stack.length - 1];
};

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function() {
  return this.stack.length === 0;
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * var obj = new MyQueue()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.empty()
 */

推荐阅读更多精彩内容