栈
栈是一种非常常见的数据结构,并且在程序中的应用非常广泛,栈和队列是比较常见的受限的线性结构。
栈结构
栈应用 -- 函数栈
所以如果一个函数不停递归,那么函数会一直加入函数调用栈,然后因为一直不会执行完,没有函数弹出,就会产生栈溢出现象!
函数栈图示
栈的实现 -- 数组方式
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>栈的封装</title>
</head>
<body>
<script>
// 封装栈类
function Stack(){
// 栈中的属性
this.items = [];
// 栈的相关操作
// 1.将元素压入栈
// 相当于给每一个对象的实例添加了方法(不要这样写)
// this.push = function(element){
// this.item.push(element);
// }
//相当于给整个对象(类)添加了方法
Stack.prototype.push = function(element){
this.items.push(element);
}
// 2.查看一下栈顶元素
Stack.prototype.peak = function(){
return this.items[this.items.length -1];
}
// 3.从栈中取出元素
Stack.prototype.pop = function(){
return this.items.pop();
}
// 4.判断是否为空栈
Stack.prototype.isEmpty = function(){
return this.items.length == 0;
}
// 5.获取栈中元素个数
Stack.prototype.size = function(){
return this.items.length;
}
// 6.toString方法
Stack.prototype.toString = function(){
return this.items.join("");
}
}
// 栈的使用
let s = new Stack();
console.log(s.isEmpty());
s.push(2);
s.push(5);
s.push(8);
s.push(10);
console.log(s);
console.log(s.isEmpty());
console.log(s.size());
console.log(s.toString());
s.pop();
console.log(s);
console.log(s.size());
console.log(s.toString());
</script>
</body>
</html>
细节问题
这里打印时会发现一个问题,第一个答打印出来的只有258
问题就出在第一步的手动展开结果那里。我们一直以来的理解是,console.log会输出当前输出结果的一个快照,这个理解确实也没错,但出于性能方面的考虑,浏览器在输出结果时,对于比较复杂的数据结构,并不会把这些数据全部展开,直到你手动戳开这些数据时,才会去获取里面的值,但是很明显,这个时候,数据已经被我们后续for循环中的操作给修改了,这就造成了一种“异步”的感觉,而事实上,整个操作其实都是同步的.
栈的应用 -- 十进制转二进制
十进制转二进制的计算过程:
计算过程是由上到下,但是转换的数是由下到上,这不就是栈的先进后出的特性吗?
代码
function dec2bin(decNum){
let stack1 = new Stack();
while(decNum > 0){ //decNum等于0时就要结束
stack1.push(decNum % 2);
decNum = Math.floor(decNum / 2);
}
let binString = "";
while(!stack1.isEmpty()){ // 因为不知道stack1的长度,所以根据是否pop到空了
binString += stack1.pop();
}
return binString;
}
console.log(dec2bin(100));