JS Stack 栈

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

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

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

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

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

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

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

使用栈判断一个单词是否是回文

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

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);
入栈
stack.pop();
stack.pop();
print(stack.size());//2
stack.print();//5 8
出栈

十进制转二进制

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

十进制转二进制
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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容