栈的讲解和练习题

目录

1.栈的讲解

2.回文数

3.进制转换

4.递归

5.佩兹糖果盒

6.括号是否匹配


1.栈的讲解

1.1 栈的入门

       栈就是和列表类似的一种数据结构,只能在栈顶添加或删除,后入先出,入栈使用push() 方法,pop()方法虽然可以访问栈顶的元素,但是调用该方法后,栈顶元素也从栈中被永久性地删除了。peek()方法则只返回栈顶元素,而不删除它。clear() 方法清除栈内所有元素,length属性记录栈内元素的个数。我们还定义了一个empty属性,用以表示栈内是否含有元素,不过使用length 属性也可以达到同样的目的。

1.2 栈的实现 

Stack.js

function Stack() {
    //用来保存栈内元素
    this.dataStore=[];
    //压栈
    this.push=function (element) {
        this.dataStore[this.dataStore.length]=element;
    }


    //出栈(出栈顶数据,先入后出)
    this.pop=function(){
        if(this.dataStore.length<1)
            return null;
        //取得最后的数据
        var buffer = this.dataStore[this.dataStore.length-1];
        //把最后的数据置空
        this.dataStore[this.dataStore.length-1]=null;
        //改变数组的长度
        this.dataStore.length--;
        //返回数据
        return buffer;
    }

    //浏览栈顶数据
    this.peek=function () {

        //获得数组的长度
        var length = this.dataStore.length;
        return this.dataStore[length-1];
    }

    //获取栈的长度
    this.length = function () {
        return this.dataStore.length;
    }

    //清空栈内数据
    this.clear=function () {
        delete this.dataStore;
        this.dataStore=[];
    }

    //遍历栈内数组
    this.forEach=function (call) {
        //1,获得数组的长度
        var length = this.dataStore.length;
        //2,遍历数据
        for(var i=length-1;i>=0;i--){
            // var item= this.dataStore[i];
            call(this.dataStore[i]);
        }
    }

}

 

栈的应用如下:

2. 回文数

回文: 一个单词、短语或数字,从前往后写和从后往前写都是一样的。比如,单词“dad”、“racecar”就是回文;如果忽略空格和             标点符号,下面这个句子也是回文,“A man, a plan, a canal: Panama”;数字1001 也是回文。

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

<script src="Stack.js"></script>
    <script>

        function isPalindrome(words) {
            //1,创建栈对象
            var stack = new Stack();
            //2,获得字符串的长度
            var length = words.length;
            //3,遍历当前的字符串和压栈,word[i]为本身值,data为压入栈后的逆序值
            for(var i=0;i<length;i++){
                stack.push(words[i]);
            }
            //输出打印
            var data='';
            stack.forEach(function (item) {
                data=data+item;
            })
            //如果当前的文字相等,就返回真
            if(words==data){
                return true;
            }else{
                return false;
            }
        }
        //控制台输出打印
        console.log(isPalindrome('abaaba'));
    </script>

 

 

3. 进制转换

进制转换:利用栈将一个数字从一种数制转换成另一种数制。

思路: 将数字n转换为以b 为基数的数字,算法如下:           

  • 最高位为n % b,将此位压入栈。
  • 使用n/b 代替n。
  • 重复步骤1 和2,直到n 等于0,且没有余数。
  • 持续将栈内元素弹出,直到栈为空,依次将这些元素排列,就得到转换后数字的字符串形式。

     

<script src="Stack.js"></script>
</head>
<body>
</body>
<script>
    function Base(num,base) {
        //创建一个栈
        var stack=new Stack();
        while(num>0){
            var buffer=num%base;
            //入栈
            stack.push(buffer);
            //向下取整
            num=Math.floor(num/base);
        }

        //通过return取出栈内元素,得到二进制(通过栈的方法取出,得到逆序值)
        var buffer="";
        stack.forEach(function (item) {
            buffer=buffer+item;
        })
        return buffer;
    }

    console.log(Base(42,2));
</script>

 

4. 递归

阶乘: 看50 的阶乘是怎么定义的: 5! = 5×4×3×2×1 = 120

思路:  递归即是程序在执行过程中不断调用自身的编程技巧

    <script src="Stack.js"></script>
    <script>

        function fact(number) {
            //1,创建栈
            var stack = new Stack();
            while(number>0){
                stack.push(number);
                number--;
            }
            var data = 1;

            //对当前的数据进行遍历,item相当于上面的number
            stack.forEach(function (item) {
                data = data*item;
            })
            return data;
        }
        console.log(fact(50));

    </script>

5. 佩兹糖果盒

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

思路:从放糖果的栈(stack)中,将不喜欢的糖果放在一个栈(getColorStack)里,将其他糖果放入一个栈(setColorAtack),最后取完糖             果后,将盛装其他糖果的栈(setColorAtack)中的糖果逐个将其放入原来的栈(stack)中,其位置将不会变化。

    <script src="Stack.js"></script>
    <script>
        //创建新栈
        var box =  new Stack();
        var sugars=['red','white','yellow'];
        
        for(var i=0;i<10;i++){
            //随机获得 0 ,1 ,2
            var index = Math.floor(Math.random()*3);
            //糖果入栈
            box.push(sugars[index]);
        }
        //显示糖的顺序
        box.forEach(function(sugar){
            console.log(sugar);
        })
        //创建新栈暂时装糖
        var buffer = new Stack();
        //将不是黄色糖果的糖果入栈
        box.forEach(function(sugar){
            if(sugar!='yellow'){
                buffer.push(sugar);
            }
        })
        //清空以前的糖盒
        box.clear();
        
        //遍历缓存糖盒,将buffer栈里的糖果移到box里
        buffer.forEach(function(sugar){
            box.push(sugar);
        })
        console.log("************************");
        //显示糖盒里面的糖
        box.forEach(function(sugar){
            console.log(sugar);
        })
        
    </script>

 

6. 括号是否匹配

<script src="Stack.js"></script>
    <script>
        // 思路:读取算术表达式,遇到左括号‘{’、‘[’、'('压入栈,
        //     栈的特点是后入先出,所以当遇到右括号‘}’、‘]’、')'
        // 的时候,取出栈顶元素,是否满足读取的右括号,栈顶是与之相
        // 匹配的左括号。最后判断栈是否为空,为空证明该表达式没有问
        // 题,否则则说明这个表达式存在括号不匹配问题。
        function matchBracket(expression) {
            //1,创建栈对象
            var stack = new Stack();
            //2,把字符串分解为数组
            var eles = expression.split('');
            for (var i = 0; i < eles.length; i++) {
                var ele = eles[i];
                //indexOf() 方法可返回某个指定的字
                // 符串值在字符串中首次出现的位置。
                if (['{', '[', '('].indexOf(ele) !== -1) {
                    stack.push(ele);
                } else {
                    //浏览栈顶元素
                    var topEle = stack.peek();
                    switch (ele) {
                        case '}':
                            if (topEle === '{') {
                                stack.pop();
                                break;
                            }
                            return i;
                        case ']':
                            if (topEle === '[') {
                                stack.pop();
                                break;
                            }
                            return i;
                        case ')':
                            if (topEle === '(') {
                                stack.pop();
                                break;
                            }
                            return i;
                        default: break;
                    }
                }
            };
            if (stack.length()) {
                return expression.length+1;
            }
            return -1;

        console.log(matchBracket('2.3 + 23 / 12 + {(3.14)]159×0.24'));
        // 返回30.

    </script>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值