一、栈(stack)
指:一种受限的线性表,后进先出(LIFO)
其限制是仅允许在 表的一端 进行插入和删除运算。这一端被称为栈顶, 相对地, 把另一端称为栈底。
LIFO(last in first out) 表示就是后进入的元素, 第一个弹出栈空间.类似于自动餐托盘, 最后放上的托盘, 往往先拿出去使用。
向一个栈插入新元素又称作进栈、 入栈或压栈, 它是把新元素放到栈顶元素的上面, 使之成为新的栈顶元素。
从一个栈删除元素又称作岀栈或退栈, 它是把栈顶元素删除掉, 使其相邻的元素成为新的栈顶元素。
二、栈的特点
先进后出,后进先出
三、程序中的栈结构
函数调用栈: A( B( C( D()))): 即A函数中调用B, B调用C, C调用D; 在A执行的过程中会将A压入栈, 随后B执行时B也被压入栈, 函数C和D执行时也会被压入栈。 所以当前栈的顺序为: A - > B - > C - > D( 栈顶); 函数D执行完之后, 会弹出栈被释放, 弹出栈的顺序为D - > C - > B - > A。
递归: 为什么没有停止条件的递归会造成栈溢出? 比如函数A为递归函数, 不断地调用自己( 因为函数还没有执行完, 不会把函数弹出栈), 不停地把相同的函数A压入栈, 最后造成栈溢出( Stack Overfloat)。
三、面试题示例
有六个元素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
解析:
顺序进栈并非一次性全部进栈,而是边进边出,而进栈顺序为 6 -> 5 -> 4 -> 3 -> 2 -> 1
A答案:65进栈,5出栈,4进栈出栈,3进栈出栈,6出栈,21进栈,1出栈,2出栈(整体入栈顺序符合654321);
B答案:654进栈,4出栈,5出栈,3进栈出栈,2进栈出栈,1进栈出栈,6出栈(整体的入栈顺序符合654321);
C答案:6543进栈,3出栈,4出栈,之后应该5出栈而不是6,所以错误;
D答案:65432进栈,2出栈,3出栈,4出栈,1进栈出栈,5出栈,6出栈。符合入栈顺序。
四、栈常见的操作
push(element)
: 添加一个新元素到栈顶位置;
pop()
: 移除栈顶的元素, 同时返回被移除的元素;
peek()
: 返回栈顶的元素, 不对栈做任何修改( 该方法不会移除栈顶的元素, 仅仅返回它);
isEmpty()
: 如果栈里没有任何元素就返回true, 否则返回false;
size()
: 返回栈里的元素个数。 这个方法和数组的length属性类似;
toString()
: 将栈结构的内容以字符串的形式返回。
五、栈结构的实现
- 封装栈类
function Stack() {
// 栈的属性
this.items = [];
// 栈的相关操作
// 1. 将元素压入栈
// 方法一:(不推荐)相当于给对象的实例添加方法
// this.push = function () { }
// 方法二:相当于给整个类添加方法,这种方式节省内存并且效率更高
Stack.prototype.push = function (element) {
this.items.push(element);
}
// 2. 从栈中取出元素
Stack.prototype.pop = function () {
return this.items