js数据结构中的栈

栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶。咖啡厅内的一摞盘子是现实世界中常见的栈的例子。只能从最上面取盘子,盘子洗净后,也只能摞在这一摞盘子的最上面。栈被称为一种后入先出(LIFO,last-in-first-out)的数据结构。

由于栈具有后入先出的特点,所以任何不在栈顶的元素都无法访问。为了得到栈底的元素,必须先拿掉上面的元素。

对栈的两种主要操作是将一个元素压入栈和将一个元素弹出栈。入栈使用 push() 方法,出栈使用 pop() 方法4

另一个常用的操作是预览栈顶的元素。 pop() 方法虽然可以访问栈顶的元素,但是调用该方法后,栈顶元素也从栈中被永久性地删除了。 peek() 方法则只返回栈顶元素,而不删除它。

为了记录栈顶元素的位置,同时也为了标记哪里可以加入新元素,我们使用变量 top ,当向栈内压入元素时,该变量增大;从栈内弹出元素时,该变量减小。push() 、 pop() 和 peek() 是栈的 3 个主要方法,但是栈还有其他方法和属性。 clear() 方法
清除栈内所有元素, length 属性记录栈内元素的个数。我们还定义了一个 empty 属性,用以表示栈内是否含有元素,不过使用 length 属性也可以达到同样的目的。

栈的实现

/**
 * Created by Administrator on 2016/12/9.
 */
function Stack() {
    this.dataStore=[];
    this.top=0;
    this.push=push;
    this.pop=pop;
    this,peek=peek;
    this.length=length;
}

/*当向栈中压入一个新元素时,需要将其保存在数组中变量 top 所对
应的位置,然后将 top 值加 1,让其指向数组中下一个空位置。*/
function push(element) {
    this.dataStore[this.top++]=element;
}

//与 push() 方法相反——它返回栈顶元素,同时将变量 top 的值减 1:
function pop() {
    return this.dataStore[--this.top];
}

//返回数组的第 top-1 个位置的元素,即栈顶元素:
function peek() {
    return this.dataStore[this.top-1];
}//如果对一个空栈调用 peek() 方法,结果为 undefined 。这是因为栈是空的,栈顶没有任何元素。

function length() {
    return this.top;
}
function clear() {
    this.top=0;
}

实例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="Stack.js"></script>
    <script>
         /********数制转换*********/
      /*  可以利用栈将一个数字从一种数制转换成另一种数制。假设想将数字 n 转换为以 b 为基数
        的数字,实现转换的算法如下。
        (1) 最高位为 n % b,将此位压入栈。
        (2) 使用 n/b 代替 n。
        (3) 重复步骤 1 和 2,直到 n 等于 0,且没有余数。
        (4) 持续将栈内*/
        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(5, 2));

      /********回文*********/
     /* 回文是指这样一种现象:一个单词、短语或数字,从前往后写和从后往前写都是一样的。
      比如,单词“dad”、“racecar”就是回文  */
     //是一个利用前面定义的 Stack 类,判断给定字符串是否是回文的程序
      function isPalindrome(word) {
          var s = new Stack();
          for (var i = 0; i < word.length; ++i) {
              s.push(word[i]);
          }
          var rword = "";
          while (s.length() > 0) {
              rword += s.pop();
          }
          if (word == rword) {
              return true;
          }
          else {
              return false;
          }
      }
      var word = "hello";
      if (isPalindrome(word)) {
          console.log(word + " is a palindrome.");
      }
      else {
          console.log(word + " is not a palindrome.");
      }
      word = "racecar"
      if (isPalindrome(word)) {
          console.log(word + " is a palindrome.");
      }
      else {
          console.log(word + " is not a palindrome.");
      }
        /* 程序的输出为:
          hello is not a palindrome.
          racecar is a palindrome.  */


         /********递归演示*********/
            //为了演示如何用栈实现递归,考虑一下求阶乘函数的递归定义。首先看看 5 的阶乘是怎么定义的:
      function factorial(n) {
          if (n === 0) {
              return 1;
          }
          else {
              return n * factorial(n-1);
          }
      }
         /*使用栈来模拟计算 5! 的过程,首先将数字从 5 到 1 压入栈,然后使用一个循环,将数字挨
          个弹出连乘,就得到了正确的答案:120。*/
      function fact(n){
             var s = new Stack();
             while (n > 1) {
                 s.push(n--);
             }
             var product = 1;
             while (s.length() > 0) {
                 product *= s.pop();
             }
             return product;
      }
         console.log(factorial(5)); // 显示 120
         console.log(fact(5)); // 显示 120
    </script>
</head>
<body>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值