学习JavaScript数据结构与算法(二)——栈

栈是一种遵从后进先出(LIFO)原则的有序集合。
新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端叫做栈底。
在栈里,新元素靠近栈顶,旧元素接近栈底。
在现实生活中也有很多栈的例子,比如餐厅里堆放的盘子,最先放的盘子在最底下,最后放的盘子在最上面。

一、栈的创建

function Stack () {

    //创建一个数组,保存栈里的元素
    var items = [];

    /*声明一些方法*/

    /*
    push(element(s))
    添加一个或几个新元素到栈顶
     */
    this.push = function(element){
        items.push(element);
    };

    /*
    pop()
    移除栈顶的元素,同时返回被移除的元素
     */
    this.pop = function(){
        return items.pop();
    };

    /*
    peek()
    返回栈顶的元素,不对栈做任何修改
    不会移除栈顶的元素,仅仅返回它
     */
    this.peek = function(){
        return items[items.length-1];
    };

    /*
    isEmpty()
    如果栈里没有任何元素就返回true,否则返回false
     */
    this.isEmpty = function(){
        return items.length == 0;
    };

    /*
    size()
    返回栈里的元素个数
    和数组的length属性类似
     */
    this.size = function(){
        return items.length;
    };

    /*
    clear()
    移除栈里的所有元素
     */
    this.clear = function(){
        items = [];
    };

    /*
    print()
    辅助方法,将栈里的元素输出到控制台
     */
    this.print = function(){
        console.log(items.toString());
    };

}

二、使用Stack类

//初始化Stack类
var stack = new Stack();
//验证栈是否为空
console.log(stack.isEmpty());  //输出为true

//向栈里添加元素
stack.push(5);
stack.push(6);
console.log(stack.peek());  //输出6

stack.push(11);
console.log(stack.size());  //输出3
console.log(stack.isEmpty());  //输出为false

//从栈里移除两个元素
stack.pop();
stack.pop();
console.log(stack.size());  //输出1
stack.print();  //输出5

使用栈

三、应用实例

1、进制转换

1)从十进制到二进制

function divideBy2 (decNumber) {
    var remStack = new Stack(),
        rem,
        binaryString = '';

    while (decNumber > 0) {
        rem = Math.floor(decNumber % 2);
        remStack.push(rem);
        decNumber = Math.floor(decNumber / 2);
    }

    while (!remStack.isEmpty()) {
        binaryString += remStack.pop().toString();
    }

    return binaryString;
}

十进制到二进制

2)从十进制到任意进制

function baseConverter (decNumber, base) {
    var remStack = new Stack(),
        rem,
        baseString = '',
        digits = '0123456789ABCDEF';

    while (decNumber > 0) {
        rem = Math.floor(decNumber % base);
        remStack.push(rem);
        decNumber = Math.floor(decNumber / base);
    }

    while (!remStack.isEmpty()) {
        baseString += digits[remStack.pop()];
    }

    return baseString;
}

十进制到任意进制

2、平衡圆括号
function parenthesesChecker (symbols) {

    let stack = new Stack(),
        balanced = true,
        index = 0,
        symbol, top,
        opens = "([{",
        closers = ")]}";

    while (index < symbols.length && balanced){
        symbol = symbols.charAt(index);
        if (opens.indexOf(symbol) >= 0){
            stack.push(symbol);
            console.log(`open symbol - stacking ${symbol}`);
        } else {
            console.log(`close symbol ${symbol}`);
            if (stack.isEmpty()){
                balanced = false;
                console.log('Stack is empty, no more symbols to pop and compare');
            } else {
                top = stack.pop();
                if (!(opens.indexOf(top) === closers.indexOf(symbol))) {
                    balanced = false;
                    console.log(`poping symbol ${top} - is not a match compared to ${symbol}`);
                } else {
                    console.log(`poping symbol ${top} - is is a match compared to ${symbol}`);
                }
            }
        }
        index++;
    }
    if (balanced && stack.isEmpty()){
        return true;
    }
    return false;
}

平衡圆括号

3、汉诺塔
function towerOfHanoi(n, from, to, helper){

    if (n > 0){
        towerOfHanoi(n-1, from, helper, to);
        to.push(from.pop());
        console.log('-----');
        console.log('Disk: ' + n);
        console.log('Source: ');
        from.print();
        console.log('Destination: ');
        to.print();
        console.log('Helper: ');
        helper.print();
        towerOfHanoi(n-1, helper, to, from);
    }
}

var source = new Stack();
source.push(3);
source.push(2);
source.push(1);

var dest = new Stack();
var helper = new Stack();

towerOfHanoi(source.size(), source, dest, helper);

【注】关于print()方法需要注意一点,该方法中已经包含了console.log()方法,直接使用就可以在控制台上打印输出。

汉诺塔

【补充】

function towerOfHanoi(n, from, to, helper){

    if (n > 0){
        towerOfHanoi(n-1, from, helper, to);
        console.log('移动盘子 ' + n + ' 从 ' + from + ' 到 ' + to);
        towerOfHanoi(n-1, helper, to, from);
    }
}

towerOfHanoi(3, 'A', 'B', 'C');

汉诺塔

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值