(1)栈是一种非常常见的数据结构,并且在程序中的应用非常广泛。
(2)定义
- 后进者先出,先进者后出,简称 后进先出(LIFO),这就是典型的栈结构。
- 新添加的或待删除的元素都保存在栈的末尾,称作
栈顶,另一端就叫栈底。 - 在栈里,新元素都靠近栈顶,旧元素都接近栈底。
- 从栈的操作特性来看,是一种 操作受限的线性表,只允许在一端插入和删除数据。
- 不包含任何元素的栈称为空栈。
(3)对比数组
- 数组
- 我们知道数组是一种线性结构,并且可以在数组的任意位置插入和删除数据
- 但是有时候,我们为了实现某些功能,必须对这种任意性加以限制
- 而栈和队列就是比较常见的受限的线性结构。
(4)特点:先进后出【重要】
- 其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对的,把另一端称为栈底。
- 向一个栈插入新元素又称为进栈、入栈或者压栈,他是把新元素放到栈顶元素的上面,使之称为新的栈顶元素。
- 从一个栈删除元素又称为出栈或退栈,他是把栈顶元素删除掉,使其相邻的元素称为新的栈顶元素。
(5)栈的操作
- push :入栈(因为栈的特点,是先进后出,所以相对于数组是尾加 即push)
- pop:出栈(因为栈的特点,是先进后出,所以相对于数组是尾删 即pop)
- peek: 返回栈顶元素,不对栈做任何修改
- isEmpty:如果栈里没有任何元素就返回true,否则返回false
- size:返回栈里的元素个数。这个方法和数组的length属性很类似
- toString:将栈结构的内容以字符串的形式返回。
<script>
//封装上述方法:
function Stack(){
this.items = []
//入栈
Stack.prototype.push = function(element){
this.items.push(element)
}
//出栈
Stack.prototype.pop = function(){
return this.items.pop()
}
//peek查看栈顶元素
Stack.prototype.peek = function(){
return this.items[this.items.length-1]
}
//检查栈是否为空
Stack.prototype.isEmpty = function(){
return this.items.length == 0
}
//栈内元素个数
Stack.prototype.size = function(){
return this.items.length
}
//转为字符串
Stack.prototype.toString = function(){
return this.items.join('')
}
}
// var stack = new Stack();
// stack.push(1)
// stack.push(2)
// console.log(stack)
</script>
(6)应用
- 栈也被用在编程语言的编译器和内存中保存变量、方法调用等,比如函数的调用栈。
- 在现实中:
- 餐厅洗盘子,最先洗完的盘子,放在最底下,一摞一摞的摆放。
- 批改作业,最后交的本子,放在最上面,最先交的,最后批改完(大多数操作)。
(7)练习题:
一列字母,A、B、C、D、E、F 顺序进栈,下列哪个是错误出栈()
A:CDEFBA
B:CDABEF
C:BAFEDC
D:EDFCBA
(8)面试题:将100转为2进制
//步骤:
100/2 = 50 ...0
50/2 = 25 ...0
25/2 = 12 ...1
12/2 = 6 ...0
6/2 = 3 ...0
3/2 = 1 ...1
1/2 = 0 ...1
结果为: 1100100
具体实现:
//方法:(需要结合上述封装的方法)
<script>
function trans2(num){
var stack = new Stack();
//循环
while(num>0){
//入栈
stack.push(num%2)
// 把整除的结果作为下一个被除数
num = Math.floor(num/2)
}
//出栈
var resturnNum = ''
//如果栈尾空,就结束出栈
while(!stack.isEmpty()){
resturnNum += stack.pop()
}
return resturnNum
}
console.log(trans2(100)) // 1100100
</script>
上述练习题的答案是:B
解释: 栈的结构是先进后出的特点,也就是按照:第一个进栈,最后一个出栈的顺序。 B选项(CDABEF): 先进入ABC --> 出C --> 进D --> 出D --> 出B --> 出A (只能先出B然后才是A)--> 进E --> 出E --> 进F --> 出F