栈是一种特殊的线性表,仅允许在表的一端进行插入和删除运算。这一端被称为栈顶(top),相对地,把另一端称为栈底(bottom)。向一个栈插入新元素又称作进栈、入栈或压栈(push),它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈(pop),它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。所以栈具有“后入先出”的特点(LIFO)。
栈的存储结构
顺序存储于链式存储都能实现一个栈,其中顺序存储的形式大概是这样:
一般的,把数组的第一个位置[0]作为栈底,再单独定义一个变量指示栈顶:
在栈的链式结构实现中,一般把链表的头指针做为栈顶,按照先后顺序来看的,这种定义与数组正好是反过来的,这是由于在顺序结构中,查找是非常方便的,插入和移动不方便。但是链式结构只知道头指针,查找不方便,但是插入方便,而对于栈而言,我们需要知道栈顶的位置,所以就干脆把链表头指针作为栈顶吧,同时由于插入方便,每次在链的开头插入一个结点很容易。
栈相关的题目
1.有效的括号
解析:
可以用map将配对的键值对储存起来。将右括号作为键,左括号作为值。遍历字符串,如果左括号不存在于map中,将左括号压入栈。右括号存在于map中,将右括号的值和左括号作比较,如果不是配对则返回false。如果配对就将栈内的该左括号删除,一直到栈为空的时候,返回true。一旦栈内不配对则输出false。
题解:
var isValid = function(s) {
const n = s.length;
if (n % 2 === 1) {
return false;
}
const pairs = new Map([
[')', '('],
[']', '['],
['}', '{']
]);
const stack = [];
for (let ch of s){
if (pairs.has(ch)) {
if (!stack.length || stack[stack.length - 1] !== pairs.get(ch)) {
return false;
}
stack.pop();
}
else {
stack.push(ch);
}
};
return !stack.length;
};