package datastructure.stack; /** * 设计一个栈,支持栈的push和pop操作,以及第三种操作findMin, 它返回改数据结构中的最小元素 * finMin操作最坏的情形下时间复杂度应该是O(1) , 简单来讲,操作一次就可以得到最小值 * @author liuxin * */ public class QuickMinStack { private int size = 0; private int index = 0; // 目前的最早入库索引 private Node head; public int findMin(){ if (head == null) { throw new RuntimeException("Stack is empty, don't have min!"); } return head.data; } public void push(int data){ if (size == 0) { head = new Node(size++, data); } else { Node temp = head; while (temp.next != null && data > temp.data) { temp = temp.next; } Node newNode = new Node(size++, data); // 未到达最后节点,或者到达最后节点,但是要插入的数据小于最后一个节点,此时插入到temp节点之前 if (unReachedLastNodeOrSmallThanLastNode(data, temp)) { insertBefore(newNode, temp); } else { // 其他情况插入到temp节点之后 insertAfter(newNode, temp); } } } private boolean unReachedLastNodeOrSmallThanLastNode(int data, Node temp) { return temp.next != null || (temp.next == null && data < temp.data); } /** * 将src节点插入到dest之前 * @param src * @param dest */ private void insertBefore(Node src, Node dest) { if (dest.prev == null) { // dest为首个元素 head = src; } else { src.prev = dest.prev; dest.prev.next = src; } dest.prev = src; src.next = dest; } /** * 将src节点插入到dest之后 * @param src * @param dest */ private void insertAfter(Node src, Node dest) { if (dest.next == null) { // temp为最后一个元素 dest.next = src; src.prev = dest; } else { dest = dest.next; insertBefore(src, dest); } } public int pop(){ Node temp = head; while (temp.next != null) { if (temp.index == this.index) { Node dest = remove(temp); return dest.data; } temp = temp.next; } if (temp.index == this.index) { Node dest = remove(temp); return dest.data; } throw new RuntimeException("Stack is Empty!"); } private Node remove(Node node) { if (node.prev == null && node.next == null) { // 唯一的元素,删除后将初始化size和index this.size = 0; this.index = 0; return node; } if (node.prev == null) { // 元素在开头位置 head = head.next; node.next.prev = null; node.next = null; } else if (node.next == null) { // 元素在结尾位置 node.prev.next = null; node.prev = null; } else { // 元素在中间位置 node.prev.next = node.next; node.next.prev = node.prev; node.prev = null; node.next = null; } this.size--; this.index++; return node; } public int size() { return size; } // 调试输出用 // @Override // public String toString() { // StringBuilder builder = new StringBuilder(size); // builder.append("["); // Node temp = head; // while (temp.next != null) { // builder.append(temp.data + ", "); // temp = temp.next; // } // builder.append(temp.data + "]"); // return builder.toString(); // } private static class Node { Node prev; int data; int index; // 插入的顺序 Node next; Node (int index, int data) { this.index = index; this.data = data; } } }