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)