数据结构——栈、相关练习代码

75 阅读2分钟

栈:受限的线性结构

规则:

栈遵循后进先出/先进后出

后进先出 Last in first out FIFO

栈的详解:

1. image.png 2. image.png 3.

image.png 4.

image.png 5.

image.png

6.注意:此时,如果想要将所有元素出栈,必须是元素4先出栈,元素3再出栈,然后再是元素1出栈

image.png

封装栈(es6):

class Stack{
// 封装栈结构
constructor(){
    this.item=[]
}
// 1.向栈顶添加元素     数组呃最后添加元素
push(ele){
    this.item.push(ele)
}
// 2.移除栈顶元素,返回栈顶元素(数组最后一个元素)
pop(){
    let  delnode=this.item.pop()
    return delnode
}
// 3.返回栈顶元素(数组最后一个元素)
peek(){
    let index=this.item.length-1
    return this.item[index]
}
// 4.判空  栈为空true  数组的length长度来判断栈是否为空
isEmpty(){
    return this.item.length==0
}
// 5.清空栈
clear(){
    this.item=[]
}
// 6.栈元素的个数==数组中元素的个数
size(){
    return this.item.length
   }
}

栈的相关面试题:

1.有六个元素6,5,4,3,2,1的顺序进栈,问以下哪一个不是合法的出栈顺序?(C)

A.5 4 3 6 1 2  B.4 5 3 2 1 6   C.3 4 6 5 2 1    D.2 3 4 1 5 6 

2.设栈的输入序列是1234,问以下哪一个不是合法的出栈顺序?(D)

A.1 2 4 3   B.2 1 3 4  C.1 2 3 4  D.4 3 1 2   E.3 2 1 4

3.设栈的输入序列是12345,问以下哪一个不是合法的出栈顺序?(B)

A.2 1 4 3 5  B.5 4 1 3 2  C.2 3 1 4 5  D.1 5 4 3 2

4.设栈的输入序列是12345,问以下哪一个是合法的出栈顺序?(D)

A.5 1 2 3 4  B.4 5 1 3 2  C.4 3 1 2 5  D.3 2 1 5 4

解析第一题的A选项:问题的关键在元素是按顺序进栈,在所有元素进栈的中间过程:栈内的元素是可以出栈的

根据题目作图:

image.png

1.A选项:将元素6,元素5压入栈内,再让元素5出栈:

image.png

2.A选项:再让元素4入栈,出栈,然后再让元素3入栈,出栈

image.png

3.选项A:让元素6出栈,再让元素2、元素1入栈

image.png

4.选项A:让元素1、元素2出栈

image.png

相关设计代码:

1.设计一个括号是否匹配的方法(栈)

匹配:({[ ]})、{()}

不匹配:({ }]、[( )

<!--1.设计一个括号是否匹配的方法(栈)  -->
<script src="Stack.js"></script>
<script>
     
    function pipei(str){
    //    如果传入的实参是左括号,就向栈顶添加元素
    // 如果传入的实参是右括号,就判断栈内的栈顶元素是否与传入的实参一致
    // 如果不一致,就返回false
    // 遍历完成,判断栈是否为空
    // 空:返回true
    // 非空:返回false
    var stack=new Stack()
    // 将传入的字符串中的元素进行遍历
    for(var i=0;i<str.length;i++){
        // 如果是下面这些左边的括号,就直接压入栈内
        if(str[i]=="("||str[i]=="["||str[i]=="{"){
            stack.push(str[i])
        }else{
            // 如果遍历到的元素不是左边的括号
            // 就判断该括号与栈内的栈顶元素对应的右括号是一致的
            // 如果是,就移除栈顶元素,并继续执行后面的代码
            // 如果不是,证明括号不匹配,就返回false,就不执行后面的代码
            switch(str[i]){
            case "}":re=stack.pop();
            if(re!="{"){
                return false
            }
            break;
            case "]":re=stack.pop();
            if(re!="["){
                return false
            }
            break;
            case ")":re=stack.pop();
            if(re!="("){
                return false
            }
            break;
            default:
                break;
        }
        }
        
    }
    // 当字符串中的所有元素遍历完后
    // 判断栈内是否还有元素
    // 如果没有,证明所有括号全部匹配成功,返回true
    // 如果仍然存在元素,返回false
        if(stack.size()==0){
            return true
        }else{
            return false
        }
    }
    console.log( pipei("({})")); //true
    console.log( pipei("({(})")); //false
</script>

2.判断当前字符串是不是回文数(栈)

 <!-- 2.判断当前字符串是不是回文数(栈) -->
<!-- 回文数:就是12321,正着读和反着是一样的 --> 
<script>
  function huiwen(str){
    // 将传入的字符串中的所有元素压入栈内
    // 再将栈内的所有元素移除
    // 判断传入的字符串与移除的字符串是否一致
    var stack=new Stack()
    var str1=""
    for(var i=0;i<str.length;i++){
        // 将字符串中的所有元素压入栈内
        stack.push(str[i])
    }
    for(var i=0;i<str.length;i++){
        // 将栈内所有元素移除
        // 并将移除的元素连接成字符串str1
        str1+=stack.pop()
    }
    console.log(str1)
    // 判断str与str1是否一致
    // 一致,返回true
    // 不一致,返回false
    if(str1==str){
        return true
    }else{
        return false
    }
  }
  console.log(huiwen("上海自来水来自海上"));
 console.log( huiwen("abba"));
</script>

3.进制转换(十进制转任意进制)(栈)

 <!--进制转换(十进制转任意进制)(栈)  -->
<script>
    function jinzhi(ele,scale){
        var arr=["A","B","C","D","E","F"]
        var stack=new Stack()
        while(ele>0){
            // 取余
            let mn=ele%scale
            if(mn>9){
                // 当余数大于9,也就意味着,是十进制转换为16进制
                // 16进制,超过9以后的数字,将以A-F字母表示
               mn=arr[mn-10]
            }
            // 将除数除以被除数后的值向下取整
            ele=Math.floor(ele/scale)
            // 将余数压入栈内
            stack.push(mn)
        }
        var str=""
        while(!stack.isEmpty()){
            // 将栈内的所有元素按顺序移除,连接成字符串
            str+=stack.pop()
        }
        // 返回一个字符串
        return str

    }
    console.log(jinzhi(100,8));
    console.log(jinzhi(100,16));
    console.log(jinzhi(100,2));
    
</script>

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

image.png

   <!-- 佩兹糖果盒 -->
<script>
    var sweetBox=new Stack();
    sweetBox.push("red")
    sweetBox.push("yellow")
    sweetBox.push("red")
    sweetBox.push("yellow")
    sweetBox.push("white")
    sweetBox.push("yellow")
    sweetBox.push("white")
    sweetBox.push("yellow")
    sweetBox.push("white")
    sweetBox.push("red")
    // 创建一个新的栈
    var Box=new Stack()
    // 判断sweetBox栈内元素的数量
    var num=sweetBox.size()
    // 遍历sweetBox栈内的所有元素
    for(var i=0;i<num;i++){
        // console.log(sweetBox.peek())
        // 如果sweetBox栈内的栈顶元素为yellow
        // 那么将这个栈顶元素移除
        if(sweetBox.peek()=="yellow"){
            sweetBox.pop()
        }else{
            // 如果栈顶元素不为yellow
            // 那么将这个栈顶元素移除,并压入到Box栈内
            Box.push(sweetBox.pop())
        }
    }
    console.log(Box);
    // 判断Box栈内元素的数量
    var num1=Box.size()
    for(var i=0;i<num1;i++){
        // 将Box栈内的所有元素移除,并压入sweetBox栈内
        sweetBox.push(Box.pop())
    }
    console.log(sweetBox);


</script>