JS Stack 栈

栈(stack)是一种遵循后进先出(Last In First Out, LIFO)的有序集合所构成的数据结构。

  • 新添加或待删除的元素保存在栈的末尾(栈顶),另一端叫做栈底。
  • 在栈里,新元素都靠近栈顶,就元素都接近栈底。
4933701-7eebbe28b78f7fc6.png

栈是和列表类似的一种高效的数据结构,由于数据只能在栈顶添加和删除,所以增删操作很快。

  • 栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,此端称为栈顶。
4933701-604e67b32d4176f0.png
入栈
  • 后进先出的栈中,任何不在栈顶的元素都无法访问。为了得到栈底元素必须先拿掉上面的元素。

  • 对栈的操作是将元素压入栈(push)和弹出栈(pop)。

4933701-d7179d94fb27bc84.png
入栈和出栈
  • 若要预览栈顶元素,pop方法虽然访问栈顶元素,但调用后栈顶元素也从栈中被永久性地被删除了。peek方法则只返回栈顶元素而不删除它。
4933701-f385254f00ea9511.png
出栈
  • 为了记录栈顶元素的位置,同时也为了标记哪里可以加入新元素,使用变量top,当向栈内压入元素时,该变量变大;当从栈内弹出元素时,该变量变小。
4933701-6b0e07deb9254cc7.png
top变量记录栈顶元素的位置

栈的实现1

/*栈类*/
function Stack(){
    this.data = [];//保存栈内元素
    this.top = 0;//记录栈顶位置

    this.push = push;
    this.pop = pop;
    this.peek = peek;

    /*辅助方法*/
    this.size = size;
    this.clear = clear;
}

/*向栈中压入新元素*/
function push(element){
    this.data[this.top++] = element;
}
/*从栈中弹出栈顶元素*/
function pop(){
    return this.data[--this.top];
}
/*预览栈顶元素,空栈返回undefined*/
function peek(){
    return this.data[this.top - 1];
}

/*获取栈内存储的元素数量*/
function size(){
    return this.top;
}
/*清空栈*/
function clear(){
    this.top = 0;
}
/*test*/
var stack = new Stack();

stack.push('David');
stack.push('Raymond');
stack.push('Bryan');
print(stack.size());//3

var poped = stack.pop();
print(poped, stack.peek());//Bryan Raymond

stack.clear();
print(stack.size());//0

数制间的相互转换

将数字n转换为b为基数的数字

  • 最高位为n%b将此位压入栈
  • 使用n/b替换n
  • 重复以上操作知道n等于0且没有余数
  • 持续将栈内元素弹出知道栈为空,依次排列元素。
// 将数字转化为二至九进制的数字
function mulBase(number,base){
    var stack = new Stack();
    do{
        stack.push(number % base);
        number =  Math.floor(number /= base);
    }while(number>0);

    var converted = '';
    while(stack.size() > 0){
        converted += stack.pop();
    };

    return converted;
}

print(mulBase(125,2), mulBase(124,8));//1111101 174

回文

回文是指这样一种现象:一个单词、短语或数字,从前往后写和从后向前写都是一样的。

  • dad、racecar
  • A man, a plan, a canal: Panama
  • 1001

使用栈判断一个字符串是否是回文,将字符串每个字符按从左到右的顺序压入栈。当字符串中的字符都入栈后,栈内就保存了一个反转后的字符串,最后的字符在栈顶,第一个字符在栈底。

4933701-6cf350356a8c9ab0.png
使用栈判断一个单词是否是回文

字符串完整压入栈内后,通过持续弹出栈中的每个字母就可以得到一个新的字符串,该字符串与原来的字符串顺序相反。最后仅需比较两个字符串即可,若相等就是一个回文。

function isPalindrom(word){
    var stack = new Stack();
    for(var i=0; i<word.length; ++i){
        stack.push(word[i]);
    }

    var rword = "";
    while(stack.size() > 0){
        rword += stack.pop();
    }

    return word == rword;
}

print(isPalindrom("hello"), isPalindrom("racecar"));//false true

递归

栈通常用来实现编程语言,使用栈实现递归即是一例。使用栈来模拟递归过程,考虑求阶乘函数的递归定义。

function factorial(n){
    if(n === 0){
        return 1;
    }else{
        return n*factorial(n-1);
    }
}
function fact(n){
    var stack = new Stack();
    while(n>1){
        stack.push(n--);
    }

    var product = 1;
    while(stack.size()>0){
        product *= stack.pop();
    }

    return product;
}

print(factorial(5), fact(5));//120 120

栈的实现2

function Stack(){
    var items = [];//保存栈内元素

    /*添加一个或多个元素到栈顶*/
    this.push = function(element){
        items.push(element);
    };
    /*移除栈顶元素同时返回被移除的元素*/
    this.pop = function(){
        return items.pop();
    };


    /*预览栈顶元素*/
    this.peek = function(){
        return items[items.length-1];
    };
    /*判断栈中是否空栈,true为空栈无元素,false为有元素。*/
    this.isEmpty = function(){
        return items.length===0;
    };
    /*返回栈内的元素个数*/
    this.size = function(){
        return items.length;
    };
    /*移除栈内的所有元素*/
    this.clear = function(){
        items = [];
    };
    /*将栈内元素输出到控制台*/
    this.print = function(){
        console.log(items.toString());
    };
}
/*test*/
var stack = new Stack();
print(stack.isEmpty());//true

stack.push(5);
stack.push(8);
print(stack.peek());//8

stack.push(11);
print(stack.size(), stack.isEmpty());//3 false

stack.push(15);
4933701-9ae196ca0343aed9.png
入栈
stack.pop();
stack.pop();
print(stack.size());//2
stack.print();//5 8
4933701-6c3c269d098dc8d4.png
出栈

十进制转二进制

要把十进制转换成二进制,可以将该十进制数字和2整除(二进制是逢二进一),知道结果为0为止。

4933701-af200fe49051ad03.png
十进制转二进制
function divideBy2(decnum){
    var stack = new Stack();
    var rem;
    while(decnum > 0){
        rem = Math.floor(decnum%2);//求模取余
        stack.push(rem);
        decnum = Math.floor(decnum/2);//商
    }

    var binary = '';
    while(!stack.isEmpty()){
        binary += stack.pop().toString();
    }
    return binary;
}
print(divideBy2(10));//1010

十进制转换成任何进制

function baseConvert(decnum, base){
    var stack = new Stack();
    var rem;
    while(decnum>0){
        rem = Math.floor(decnum%base);
        stack.push(rem);
        decnum = Math.floor(decnum/base);
    }

    var basestr = "";
    var digits = "0123456789ABCDEF";
    while(!stack.isEmpty()){
        basestr += digits[stack.pop()];
    }
    return basestr;
}
print(baseConvert(100345,2),baseConvert(100345,8),baseConvert(100345,16));//11000011111111001 303771 187F9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值