链表 单向链表 1 2 3 4 5 6 7 8 public class Node { private int value; private Node next; public Node (int value) { this .value = value; } }
双向链表 1 2 3 4 5 6 7 8 9 public class DoubleNode { private int value; private DoubleNode last; private DoubleNode next; public DoubleNode (int value) { this .value = value; } }
1. 链表反转 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 public Node reverseLinkedList (Node head) { Node pre = null ; Node next = null ; while (head != null ) { next = head.next; head.next = pre; pre = head; head = next; } return pre; } public DoubleNode reverseDoubleLinkedList (DoubleNode head) { DoubleNode pre = null ; DoubleNode next = null ; while (head != null ) { next = head.next; head.next = pre; head.last = next; pre = head; head = next; } return pre; }
2. 给定值删除 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public static Node removeValue (Node head, int num) { while (head != null ) { if (head.value != num) { break ; } head = head.next; } Node pre = head; Node cur = head; while (cur != null ) { if (cur.value == num) { pre.next = cur.next; } else { pre = cur; } cur = cur.next; } return head; }
栈和队列 栈:数据先进后出,犹如弹匣 队列:数据先进先出,好似排队
栈和队列的实际实现方式:
1. 双向链表实现栈和队列 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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 public class LinkedListToQueueAndStack { public static class Node <V > { private V value; private Node<V> next; public Node (V v) { this .value = v; next = null ; } } public static class MyQueue <V > { private Node<V> head; private Node<V> tail; private int size; public boolean isEmpty () { return size == 0 ; } public int size () { return this .size; } public void offer (V v) { Node<V> cur = new Node<V>(v); if (tail == null ) { head = cur; tail = cur; } else { tail.next = cur; tail = cur; } size++; } public V poll () { V ans = null ; if (head != null ) { ans = head.value; head = head.next; size--; } if (head == null ) { tail = null ; } return ans; } public V peek () { V ans = null ; if (head != null ) { ans = head.value; } return ans; } } public static class MyStack <V > { private Node<V> head; private int size; public boolean isEmpty () { return size == 0 ; } public int size () { return this .size; } public void push (V v) { Node<V> cur = new Node<V>(v); if (head == null ) { head = cur; } else { cur.next = head; head = cur; } size++; } public V pop () { V ans = null ; if (head != null ) { ans = head.value; head = head.next; size--; } return ans; } public V peek () { return head != null ? head.value : null ; } } }
2. 数组实现栈和队列 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 public class ArrayToQueueAndStack { public static class MyQueue { private int [] arr; private int pushi; private int polli; private int size; private final int limit; public MyQueue (int limit) { arr = new int [limit]; pushi = 0 ; polli = 0 ; size = 0 ; this .limit = limit; } public void push (int value) { if (size == limit) { throw new RuntimeException("队列满了,不能再加了" ); } size++; arr[pushi] = value; pushi = nextIndex(pushi); } public int poll () { if (size == 0 ) { throw new RuntimeException("队列空了,不能再拿了" ); } size--; int ans = arr[polli]; polli = nextIndex(polli); return ans; } public boolean isEmpty () { return size == 0 ; } private int nextIndex (int i) { return i < limit - 1 ? i + 1 : 0 ; } } public static class MyStack { private int top = -1 ; private int [] arr; public MyStack (int length) { arr = new int [length]; } public void push (int num) { if (top > arr.length - 1 ) { throw new RuntimeException("栈满了,不能再加了" ); } arr[++top] = num; } public int pop () { if (top < 0 ) { throw new RuntimeException("栈空了,不能再拿了" ); } return arr[top--]; } } }
3. 实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能 要求:
pop、push、getMin操作的时间复杂度都是O(1)
设计的栈类型可以使用现成的栈结构
思路: 两个栈:数据栈+最小栈 push时,数据栈正常压入,最小栈压入当前最小值 pop时,数据栈弹出返回,最小栈弹出 getMin,最小栈peek
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 public static class MyStack { private Stack<Integer> stackData; private Stack<Integer> stackMin; public MyStack () { this .stackData = new Stack<Integer>(); this .stackMin = new Stack<Integer>(); } public void push (int newNum) { if (this .stackMin.isEmpty()) { this .stackMin.push(newNum); } else if (newNum < this .getmin()) { this .stackMin.push(newNum); } else { int newMin = this .stackMin.peek(); this .stackMin.push(newMin); } this .stackData.push(newNum); } public int pop () { if (this .stackData.isEmpty()) { throw new RuntimeException("Your stack is empty." ); } this .stackMin.pop(); return this .stackData.pop(); } public int getmin () { if (this .stackMin.isEmpty()) { throw new RuntimeException("Your stack is empty." ); } return this .stackMin.peek(); } }
4. 栈实现队列,队列实现栈 栈实现队列思路: 两个栈实现队列,一个push栈一个pop栈,队列push压入push栈,队列poll从pop弹出
从push栈倒数据到pop栈要一次性倒完
pop栈空了才能倒数据
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 public static class TwoStacksQueue { public Stack<Integer> stackPush; public Stack<Integer> stackPop; public TwoStacksQueue () { stackPush = new Stack<Integer>(); stackPop = new Stack<Integer>(); } private void pushToPop () { if (stackPop.empty()) { while (!stackPush.empty()) { stackPop.push(stackPush.pop()); } } } public void add (int pushInt) { stackPush.push(pushInt); pushToPop(); } public int poll () { if (stackPop.empty() && stackPush.empty()) { throw new RuntimeException("Queue is empty!" ); } pushToPop(); return stackPop.pop(); } public int peek () { if (stackPop.empty() && stackPush.empty()) { throw new RuntimeException("Queue is empty!" ); } pushToPop(); return stackPop.peek(); } }
队列实现栈思路: 两个队列,push进第一个队列,pop时poll第一个队列所有元素,如果是第一个队列最后一个值直接返回,如果不是push进第二个队列
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 public static class TwoQueueStack <T > { public Queue<T> queue; public Queue<T> help; public TwoQueueStack () { queue = new LinkedList<>(); help = new LinkedList<>(); } public void push (T value) { queue.offer(value); } public T poll () { while (queue.size() > 1 ) { help.offer(queue.poll()); } T ans = queue.poll(); Queue<T> tmp = queue; queue = help; help = tmp; return ans; } public T peek () { while (queue.size() > 1 ) { help.offer(queue.poll()); } T ans = queue.poll(); help.offer(ans); Queue<T> tmp = queue; queue = help; help = tmp; return ans; } public boolean isEmpty () { return queue.isEmpty(); } }