JavaScript算法练习之栈

什么是栈

栈就是和列表类似的一种数据结构,它可用来解决计算机世界里的很多问题。栈是一种高 效的数据结构,因为数据只能在栈顶添加或删除,所以这样的操作很快,而且容易实现。 栈的使用遍布程序语言实现的方方面面,从表达式求值到处理函数调用。
栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶。
栈被称为一种后入先出(LIFO,last-in-first-out)的数据结构。

栈的实现

在JavaScript中,我们可以用如下函数实现栈:

function Stack(){
    this.dataStore = []; //使用数组保存栈内元素
    this.top=0; //记录栈顶位置,初始化为0
    this.push = push; // 向栈中压入一个新元素
    this.pop = pop; // 从栈顶推出一个元素
    this.peek = peek; // 返回栈顶元素
    this.clear=clear; //清除栈
    this.length=length;//返回栈的元素个数
}
//当向栈中压入一个新元素时,需要将其保存在数组中变量 top 所对 应的位置,
//然后将 top 值加 1,让其指向数组中下一个空位置。
function push(element){
    this.dataStore[this.top++]=element;
}

//它返回栈顶元素,同时将变量 top 的值减 1
function pop(){
    return this.dataStore[--this.top];
}
//返回数组的第 top-1 个位置的元素,即栈顶元素:
function peek(){
    return this.dataStore[this.top-1];
}
//通过返回变量 top 值的方式返回栈 内的元素个数
function length(){
    return this.top;
}
//清空一个栈
function clear(){
    this.top = 0;
}

以下所有算法题目,都是依据Stack函数的。

实战练习

习题一

利用栈将一个数字从一种数制转换成另一种数制。假设想将数字 n 转换为以 b 为基数
的数字,实现转换的算法如下。
(1) 最高位为 n % b,将此位压入栈。
(2) 使用 n/b 代替 n。
(3) 重复步骤 1 和 2,直到 n 等于 0,且没有余数。
(4) 持续将栈内元素弹出,直到栈为空,依次将这些元素排列,就得到转换后数字的字符
串形式。
此算法只针对基数为2~9的情况

代码如下:

function mulBase(num, base) {
var s = new Stack();
do {
    s.push(num % base);
    num = Math.floor(num / base);
} while (num > 0)
var converted = "";
while (s.length() > 0) {
    converted += s.pop();
}
  return converted;
}

console.log(mulBase(32, 2)); // 100000

习题二

判断给定字符串是否是回文

思路:

从左往右把字符串的每一个字符,依次放入栈中,最后从栈的顶部往底部看去,就是一个反过来的字符串。我们只要依次将字符串弹出,组成一个新的字符串,与原来的字符串进行比较即可。相等的话,就是回文,反之,不是回文。

代码如下:

function isPalindrome(word){
  var s = new Stack();
  for(var i=0;i<word.length;++i){
      s.push(word[i]);
  }
  var newWord = '';
  while(s.length()>0){
      newWord += s.pop();
  }
  if(newWord === word){
      return true;
  }else{
      return false;
  }
}

console.log(isPalindrome("racecar")); // true
console.log(isPalindrome("hello")); // false

习题三

使用栈来实现阶乘函数

思路:

首先将数字从 num 到 1 压入栈,然后使用一个循环,将数字挨
个弹出连乘,就得到了正确的答案

代码如下:

function factorial(num){
  var s = new Stack();
  while(num>1){
      s.push(num--);
  }
  var product = 1;
  while(s.length()>0){
      product *= s.pop();
  }
  return product;
}
console.log(factorial(5));   //120

习题三

用栈来判断一个表达式中的括号(仅有一种括号,小、中或大括号)是否配对.编写并实现它的算法.

思路:

function isMatch(str){
var s = new Stack;
var bracket = '';
for(var i=0;i<str.length;i++){
    bracket = str[i];
    if(bracket === "(" || bracket === "[" || bracket === "{"){
        s.push(bracket)
    }else if(bracket === ")" || bracket === "]" || bracket === "}") {
        if(s.length()>0){
            s.pop()
        }else {
            return '括号不匹配';
        }
    }
  }
  if(s.length()>0){
      return '括号不匹配'
  }
    return '匹配';
}
console.log(isMatch('1+2*(2+1')); // 括号不匹配
console.log(isMatch('1+2*(2+1)')); // 匹配
console.log(isMatch('1+2*(2+1)+(2*2+1')); // 括号不匹配
console.log(isMatch('1+2*(2+1)+(2*2+1)')); // 匹配

习题四

现实生活中栈的一个例子是佩兹糖果盒。想象一下你有一盒佩兹糖果,里面塞满了红 色、黄色和白色的糖果,但是你不喜欢黄色的糖果。使用栈(有可能用到多个栈)写一 段程序,在不改变盒内其他糖果叠放顺序的基础上,将黄色糖果移出。

思路

除了糖果盒,还需要俩个栈。一个用来存放黄色糖果,一个用来存放其他糖果。首先将糖果盒中的糖一个个弹出,压入目标栈中。当糖果盒中的糖全都弹出后,把存放其他糖果的栈中的糖一个个弹出,压入糖果盒中,这样就得到想要的结果了。

代码如下:

// 假设盒子中放着这些糖果
var sweetBox = new Stack();

sweetBox.push('yellow');
sweetBox.push('white');
sweetBox.push('yellow');
sweetBox.push('white');
sweetBox.push('red');
sweetBox.push('red');
sweetBox.push('yellow');
sweetBox.push('red');
sweetBox.push('yellow');
sweetBox.push('white');

console.log(sweetBox.dataStore);

function selectYellow(){
    var yellow  = new Stack(); //放置黄色糖果
    var other = new Stack(); //放置其他糖果
    var one = '';
    while(sweetBox.length()>0){
    var one = sweetBox.pop();
    if(one === 'yellow'){
        yellow.push(one);
    }else{
        other.push(one);
    }
}
while(other.length()>0){
    sweetBox.push(other.pop());
}
    return sweetBox;
}
console.log(selectYellow().dataStore);

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

推荐阅读更多精彩内容

  • 栈(Stack) 上一篇我们说到了列表,它是一种最自然的数据组织方式,如果对数据的存储顺序要求不重要,那么列表就是...
    Cryptic阅读 15,525评论 7 15
  • Unicode®标准附录#9 UNICODE双向算法#### 摘要#### 本附件是一份关于字符定位的规范,主要描...
    Eriice阅读 4,572评论 0 6
  • 我没有辜负自己的期望,在我18岁这一年,我成为了我一直以来希望成为的人类品种之一---渣男。 我很擅长给自己找...
    第九天堂阅读 208评论 0 0
  • 在新西兰微留学体验,租车自驾是最好的选择。因为可以在孩子上学的空档自由地在周边体验新西兰的风土人情。但在新西兰车的...
    大观家庭阅读 449评论 0 0
  • 【尽力而为】20170728-D74 1动脑贴贴画2-3岁,开始贴最后一本语言篇,故事相对长,读完贴了1页。 2磁...
    小君爱未未阅读 120评论 0 0