定义
在计算机科学中,stack是一种线性的数据结构,只能在其一端添加数据和移除数据。习惯来说,这一端称之为栈顶,另一端不能操作数据的称之为栈底,就像一个装书的容器一样,放从最上面放,拿从最上面拿。
常见的栈方法接口实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public interface Stack<E> {
boolean push(E value);
E pop();
E peek();
boolean isEmpty();
boolean isFull(); }
|
单向链表实现栈
和队列差不多,就是少了一个尾指针,不在尾部拿值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| public class LinkedListStack<E> implements Stack<E> ,Iterable<E>{
private int capacity; private int size; private Node<E> head = new Node<>(null, null);
public LinkedListStack(int capacity) { this.capacity = capacity; }
static class Node<E> { E value; Node<E> next;
public Node(E value, Node<E> next) { this.value = value; this.next = next; } }
@Override public boolean push(E value) { if(isFull()) { return false; } head.next = new Node<>(value, head.next); size++; return true; }
@Override public E pop() { if(isEmpty()) { return null; } Node<E> first = head.next; head.next = first.next; size--; return first.value; }
@Override public E peek() { if(isEmpty()) { return null; } return head.next.value; }
@Override public boolean isEmpty() { return size == 0; }
@Override public boolean isFull() { return size == capacity; }
@Override public Iterator<E> iterator() { return new Iterator<E>() { Node<E> p = head.next; @Override public boolean hasNext() { return p != null; }
@Override public E next() { E value = p.value; p = p.next; return value; } }; } }
|
数组实现栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| public class ArrayStack<E> implements Stack<E>, Iterable<E>{
private E[] array; private int top;
@SuppressWarnings("all") public ArrayStack(int capacity) { this.array = (E[]) new Object[capacity]; }
@Override public boolean push(E value) { if(isFull()) { return false; } array[top++] = value; return true; }
@Override public E pop() { if(isEmpty()) { return null; } return array[--top]; }
@Override public E peek() { if(isEmpty()) { return null; } return array[top - 1]; }
@Override public boolean isEmpty() { return top == 0; }
@Override public boolean isFull() { return top == array.length; }
@Override public Iterator<E> iterator() { return new Iterator<E>() { int p = top; @Override public boolean hasNext() { return p > 0; }
@Override public E next() { return array[--p]; } }; } }
|
力扣关于栈的题
有效的括号 T20
遍历字符串每位字符比较,出现左括号存入相对应的右括号到栈中,接着出现右括号就进行比对,比对失败就是false
1 2 3 4 5 6 7 8 9 10
| public boolean isValid(String s) { Stack<Character>stack = new Stack<Character>(); for(char c: s.toCharArray()){ if(c=='(')stack.push(')'); else if(c=='[')stack.push(']'); else if(c=='{')stack.push('}'); else if(stack.isEmpty()||c!=stack.pop())return false; } return stack.isEmpty(); }
|
逆波兰表达式求值 T150
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| public int evalRPN(String[] tokens) {
LinkedList<Integer> stack = new LinkedList<>(); for (String token : tokens) { switch (token) { case "+" : { Integer b = stack.pop(); Integer a = stack.pop(); stack.push(a+b); break; } case "-" : { Integer b = stack.pop(); Integer a = stack.pop(); stack.push(a-b); break; } case "*" : { Integer b = stack.pop(); Integer a = stack.pop(); stack.push(a*b); break; } case "/" : { Integer b = stack.pop(); Integer a = stack.pop(); stack.push(a/b); break; } default: { stack.push(Integer.parseInt(token)); } } } return stack.pop(); }
|
双栈实现队列 T232
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| LinkedList<Integer> s1 = new LinkedList<>(); LinkedList<Integer> s2 = new LinkedList<>();
public void push(int x) { s2.push(x); }
public int pop() { if(s1.isEmpty()) { while(!s2.isEmpty()) { s1.push(s2.pop()); } } return s1.pop(); }
public int peek() { if(s1.isEmpty()) { while(!s2.isEmpty()) { s1.push(s2.pop()); } } return s1.peek(); }
public boolean empty() { return s1.isEmpty() && s2.isEmpty(); }
|
单队列实现栈 T225
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| Queue<Integer> a;
int i;
public void push(int x) { a.offer(x); for (int j = 0; j < i; j++) { a.offer(a.poll()); } i++; }
public int pop() { i--; return a.poll(); }
public int top() { return a.peek(); }
public boolean empty() { return a.isEmpty(); }
|