栈是一种特殊的线性表,仅允许在表的一端进行插入和删除运算。这一端被称为栈顶(top),相对地,把另一端称为栈底(bottom)。向一个栈插入新元素又称作进栈、入栈或压栈(push),它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈(pop),它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。所以栈具有“后入先出”的特点(LIFO)。

栈的存储结构
顺序存储于链式存储都能实现一个栈,其中顺序存储的形式大概是这样:
栈 - 图1
一般的,把数组的第一个位置[0]作为栈底,再单独定义一个变量指示栈顶:
在栈的链式结构实现中,一般把链表的头指针做为栈顶,按照先后顺序来看的,这种定义与数组正好是反过来的,这是由于在顺序结构中,查找是非常方便的,插入和移动不方便。但是链式结构只知道头指针,查找不方便,但是插入方便,而对于栈而言,我们需要知道栈顶的位置,所以就干脆把链表头指针作为栈顶吧,同时由于插入方便,每次在链的开头插入一个结点很容易。

那么栈的链式存储的形式大概是这样:
栈 - 图2

栈相关的题目

1.有效的括号

image.png
image.png

解析:

可以用map将配对的键值对储存起来。将右括号作为键,左括号作为值。遍历字符串,如果左括号不存在于map中,将左括号压入栈。右括号存在于map中,将右括号的值和左括号作比较,如果不是配对则返回false。如果配对就将栈内的该左括号删除,一直到栈为空的时候,返回true。一旦栈内不配对则输出false。

题解:

  1. var isValid = function(s) {
  2. const n = s.length;
  3. if (n % 2 === 1) {
  4. return false;
  5. }
  6. const pairs = new Map([
  7. [')', '('],
  8. [']', '['],
  9. ['}', '{']
  10. ]);
  11. const stack = [];
  12. for (let ch of s){
  13. if (pairs.has(ch)) {
  14. if (!stack.length || stack[stack.length - 1] !== pairs.get(ch)) {
  15. return false;
  16. }
  17. stack.pop();
  18. }
  19. else {
  20. stack.push(ch);
  21. }
  22. };
  23. return !stack.length;
  24. };