【Javascript】栈和队列的实现

前言

我们知道栈的原理是先进后出,队列的原理是先进先出。

在JS中主要通过数组来实现队列和数组的功能。

首先我们来看栈

入栈可以用 arr.push()

出栈可以用 arr.pop()

然后是队列

入队可以用 arr.push()

出队可以用 arr.shift()


接下来通过两道经典的题目来进一步熟悉栈和队列

leetcode 232 用栈实现队列

题目链接
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty

主要思路:

我们需要用两个栈,一个负责入队stackIn,一个负责出队stackOut。

入队push()的时候,直接压入stackIn中即可,重点在于出队的操作。在pop()时如果stackOut为空,则将stackIn全部数据都导入stackOut,这样一来,stackOut栈顶元素就是第一个入栈的元素,也就是我们需要出队的元素。如果stackOut不为空,则直接出栈弹出数据即可。

判断队列是否为空,只需要stackIn和stackOut均为空即说明队列为空。

具体代码实现:

var MyQueue = function() {
    this.stackIn = [];
    this.stackOut = [];
};

/** 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function(x) {
    this.stackIn.push(x)
};

/**
 * @return {number}
 */
MyQueue.prototype.pop = function() {
    if(this.stackOut.length){
        return this.stackOut.pop();
    }
    while(this.stackIn.length !== 0){
        this.stackOut.push(this.stackIn.pop());
    }
    return this.stackOut.pop();
};

/**
 * @return {number}
 */
MyQueue.prototype.peek = function() {
    const x = this.pop();
    this.stackOut.push(x);
    return x;
};

/**
 * @return {boolean}
 */
MyQueue.prototype.empty = function() {
    return !this.stackIn.length && !this.stackOut.length;
};

/**
 * 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()
 */

leetcode 225 用队列实现栈

题目链接

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

主要思路:

由于队列是先进先出,这个题目肯定不能和leetcode232一样。但我们同样是使用两个队列queue1和queue2。queue2主要的作用其实是备份,存储最后一个“入栈”元素以外的所有元素。这样可以保证queue1中队首元素始终是栈顶元素。

入栈我们还是直接压入queue1即可。重点在于出栈操作,我们刚才也介绍过要做到栈顶元素就是queue1队首元素。因此 当queue1中元素个数大于1时,就将其pop()出去存储在queue2中。(这样可以保证que1中只有栈顶元素)。这里需要注意的一点是,如果已经出栈一次,queue1就会为空,此时我们需要将queue1与queue2进行交换。(如果交换后queue1元素个数大于1,会重复之前的操作)。

具体代码实现:

var MyStack = function() {
    this.queue1 = [];
    this.queue2 = [];
};

/** 
 * @param {number} x
 * @return {void}
 */
MyStack.prototype.push = function(x) {
    this.queue1.push(x);
};

/**
 * @return {number}
 */
MyStack.prototype.pop = function() {
    if(!this.queue1.length){
        [this.queue1, this.queue2] = [this.queue2, this.queue1];
    }
    while(this.queue1.length > 1){
        this.queue2.push(this.queue1.shift());
    }
    return this.queue1.shift();
};

/**
 * @return {number}
 */
MyStack.prototype.top = function() {
    const x = this.pop();
    this.queue1.push(x);
    return x;
};

/**
 * @return {boolean}
 */
MyStack.prototype.empty = function() {
    return !this.queue1.length && !this.queue2.length;
};

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

栈和队列还有许多经典的题目,如:leetcode 20 有效的括号leetcode 150 逆波兰表达式求值,感兴趣的朋友也可以自己尝试做一下, 巩固自己对栈和队列的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值