1.什么是函数调用栈? A调用了B,B调用了C,C调用了D 在函数A 执行的时候,A 进入栈中,但是因为A中调用B函数,所以A函数在并没有弹出的时候,B进行栈中,因为B函数中调用了C函数,所以B函数也没有进行弹出而且C函数进栈,同样的道理类推~~于是就有了函数调用栈 2.为什么递归调用的时候,会有栈溢出的问题? 因为递归函数的调用就是在不断的调用自身的函数,自身的函数一直进栈进栈,但是没有弹出,所以会出现栈溢出的问题 3.栈的面试题 (1)下面有6个元素6,5,4,3,2,1,依次进栈,哪一个出栈顺序是不合法的?
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
答案是:注意按顺序进栈标识不是一次性全部进,首先根据第一个出栈的数字,分析当前的栈的结构。数值越大越在底部,可以一边进栈一边出栈(答案是C) 分析A:当第一个出栈元素为5 的时候,当前的栈的结构是 B分析 C分析 D分析 4.栈代码的实现(基于数组或者基于链表)
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]; //返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)。 }; this.isEmpty = function(){ return items.length == 0; // 如果栈里没有任何元素就返回true,否则返回false。 }; this.size = function(){ return items.length; //返回栈里的元素个数。 }; this.clear = function(){ items = []; //移除栈里的所有元素。 }; this.print = function(){ console.log(items.toString()); }; }方法:与某一个对象实例相关
5.Stack类的应用,十进制转二进制 要把十进制转化成二进制,我们可以将该十进制数字和2整除(二进制是满二进一),直到结 果是0为止。 例如:100 100/2 余数0 50/2 余数0 25/2 余数1 12/2 余数0 6/2 余数0 3/2 余数1 1/2 余数1
将余数从下往上串连起来得到---->1100100,这个就是十进制100转为二进制的表示方法 其实这个转换的过程就相当于100/2开始不断地将余数入栈,然后最后再将余数依次出栈串连起来 代码实现
function coverToBase(number,base){ // 基于上面Stack类创建一个实例 var stack = new Stack() var numstr = '',num=''; while(number > 0){ // 获取余数num num = Math.floor(number % base) stack.push(num) // 更新number number = Math.floor(number / base) } while(!stack.isEmpty()){ numstr += stack.pop().toString(); } return numstr } let data = coverToBase(100,2) console.log(data)