反转单链表
public Node reverseLinkedList(Node head) {if (head == null || head.next == null) {return head;}Node prev = null;Node next = null;while (head != null) {next = head.next;head.next = prev;prev = head;head = next;}return prev;}
反转双链表
public DoubleNode reverseDoubleLinkedList(DoubleNode head) {if (head == null || head.next == null) {return head;}DoubleNode prev = null;DoubleNode next = null;while (head != null) {next = head.next;head.next = prev;head.prev = next;prev = head;head = next;}return prev;}
在链表中删除指定值的所有节点
public Node removeValue(Node head, int value) {if (head == null) {return head;}//考虑头节点开始就是需要删除的节点while (head != null && head.value == value) {head = head.next;}Node prev = null;Node curr = head;while (curr != null) {if (curr.value == value) {prev.next = curr.next;} else {prev = curr;}curr = curr.next;}return head;}
用双链表实现栈和队列
可先实现双端队列, 使用双端队列实现队列(先进先出) 使用双端队列实现栈(先进后出)
//双端队列实现方法public class DoubleEndsQueue<T> {private Node<T> head;private Node<T> tail;private int size;//从头部添加public void addFromHead(T value) {Node<T> node = new Node<>(value);if (head == null) {head = node;tail = node;} else {node.next = head;head.prev = node;head = node;}size++;}//从底部添加public void addFromBottom(T value) {Node<T> node = new Node<>(value);if (tail == null) {tail = node;head = tail;} else {tail.next = node;node.prev = tail;tail = node;}size++;}//从头部获取public T popFromHead() {if (head == null) {return null;}Node<T> result = head;if (head == tail) {head = null;tail = null;} else {head = head.next;head.prev = null;result.next = null;}size--;return result.value;}//从底部获取public T popFromBottom() {if (tail == null) {return null;}Node<T> result = tail;if (head == tail) {head = null;tail = null;} else {tail = tail.prev;tail.next = null;result.prev = null;}size--;return result.value;}public int getSize() {return size;}public boolean isEmpty() {return size == 0;}}
用环形数组实现栈和队列
技巧:在数据结构中增加一个size变量,如此可免去判断读写子指针相交问题
//队列的实现public static class RingArrayQueue<T> {private Object[] arr;private int limit;private int size;private int readIdx = 0;private int writeIdx = 0;public RingArrayQueue(int maxSize) {if (maxSize < 1) {throw new InvalidParameterException("最大值需大于0,maxSize: " + maxSize);}this.limit = maxSize;this.arr = new Object[maxSize];}public void put(T value) {if (size == limit) {throw new RuntimeException("容量满了");}arr[writeIdx++] = value;writeIdx = writeIdx == limit ? 0 : writeIdx;size++;}public T pop() {if (size == 0) {throw new RuntimeException("没有数据啦");}Object result = arr[readIdx++];readIdx = readIdx == limit ? 0 : readIdx;size--;return (T) result;}public int getSize() {return size;}public boolean isEmpty() {return size == 0;}}
//栈的实现public class MyStack<T> {private Object[] arr;private int limit;private int size;private int writReadIdx;public MyStack(int limit) {if (limit < 1) {throw new RuntimeException("limit需大于0");}this.limit = limit;arr = new Object[limit];}public void push(T value) {if (size == limit) {throw new RuntimeException("容量满了");}arr[writReadIdx++] = value;writReadIdx = writReadIdx == limit ? 0 : writReadIdx;size++;}public T pop() {if (size == 0) {throw new RuntimeException("没有值了");}writReadIdx = writReadIdx - 1 < 0 ? limit - 1 : --writReadIdx;size--;return (T) arr[writReadIdx];}public int size() {return size;}public boolean isEmpty() {return size == 0;}}
实现有getMin功能的栈
利用两个栈,一个栈记录数据,另一个栈同步记录当前最小的值
public class GetMinStack {private Stack<Integer> data;private Stack<Integer> min;public GetMinStack() {this.data = new Stack<>();this.min = new Stack<>();}public void push(int value) {if (min.isEmpty()) {min.push(value);} else {Integer preMin = min.peek();min.push(Math.min(preMin, value));}data.push(value);}public int pop() {min.pop();return data.pop();}public int getMin() {return min.peek();}}
两个栈实现队列
弹出栈为空的时候才从写入栈去导入 写入栈导入弹出栈时需一次性导完
public class TwoStackQueue<T> {private Stack<T> push;private Stack<T> pop;public TwoStackQueue() {this.push = new Stack<>();this.pop = new Stack<>();}public void push(T value) {push.push(value);}public T poll() {pushToPop();return pop.pop();}private void pushToPop() {if (pop.isEmpty() && !push.isEmpty()) {while (!push.isEmpty()) {pop.push(push.pop());}}}public T peek() {pushToPop();return pop.peek();}public boolean isEmpty() {return pop.isEmpty() && pop.isEmpty();}}
两个队列实现栈
弹出数据的时候,将主队列数据移动到辅助队列,再将主队列和辅助队列应用交换
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();}}
