diff --git a/729 b/729 new file mode 100644 index 0000000000000000000000000000000000000000..6abf1626921824c6ea45072897fadd97f9d51b4f --- /dev/null +++ b/729 @@ -0,0 +1,345 @@ +public class ResizingArrayStack implements Iterable { + private Item[] a; // 数组表示栈,栈顶在最大的下标。 + private int n; // 栈内元素的个数 + + + /** + * 初始化一个空栈 + */ + public ResizingArrayStack() { + a = (Item[]) new Object[2]; + n = 0; + } + + /** + * 判断栈内是否有元素 + */ + public boolean isEmpty() { + return n == 0; + } + + /** + * 返回栈内元素个数 + */ + public int size() { + return n; + } + + // 改变栈的大小 + private void resize(int capacity) { + assert capacity >= n; + // 注意不能直接创建泛型数组 + Item[] temp = (Item[]) new Object[capacity]; + for (int i = 0; i < n; i++) { + temp[i] = a[i]; + } + a = temp; + // 也可以选择下面这种方式改变数组大小 + // a = java.util.Arrays.copyOf(a, capacity); + } + + /** + * 压入元素 + */ + public void push(Item item) { + //先判断n的大小,如果栈满则改变栈的大小 + if (n == a.length) resize(2*a.length); + a[n++] = item; + } + + /** + * 弹出并返回元素 + */ + public Item pop() { + if (isEmpty()) throw new NoSuchElementException("Stack underflow"); + Item item = a[n-1]; + a[n-1] = null; //防止对象游离 + n--; + // 如果有必要则调整栈的大小 + if (n > 0 && n == a.length/4) resize(a.length/2); + return item; + } + + + /** + * 返回但不弹出栈顶元素 + */ + public Item peek() { + if (isEmpty()) throw new NoSuchElementException("Stack underflow"); + return a[n-1]; + } + + /** + * 返回一个可以进行先进后出迭代的迭代器 + */ + public Iterator iterator() { + return new ReverseArrayIterator(); + } + + // 用内部类实现迭代器接口,实现从栈顶往栈底的先进后出迭代,没有实现remove()方法。 + private class ReverseArrayIterator implements Iterator { + private int i; + public ReverseArrayIterator() { + i = n-1; + } + public boolean hasNext() { + return i >= 0; + } + public void remove() { + throw new UnsupportedOperationException(); + } + public Item next() { + if (!hasNext()) throw new NoSuchElementException(); + return a[i--]; + } + } + + + /** + * 测试 + */ + public static void main(String[] args) { + ResizingArrayStack stack = new ResizingArrayStack(); + while (!StdIn.isEmpty()) { + String item = StdIn.readString(); + if (!item.equals("-")) stack.push(item); + else if (!stack.isEmpty()) StdOut.print(stack.pop() + " "); + } + StdOut.println("(" + stack.size() + " left on 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 + 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 + 110 + + 链表实现栈:需要一个静态内部类Node作为链表,first节点作为栈顶,压入、弹出元素相当于在链表头插入和删除节点,内部类实现Iterator接口用于迭代。具体细节看注释: + +public class Stack implements Iterable { + private Node first; //栈顶节点 + private int N; // 栈内元素数量 + + // 辅助类Node,用于形成链表 + private static class Node { + private Item item; + private Node next; + } + + /** + * 初始化栈 + */ + public Stack() { + first = null; + N = 0; + } + + /** + * 判断栈是否为空 + */ + public boolean isEmpty() { + return first == null; + //return N == 0; + } + + /** + * 返回栈内元素数量 + */ + public int size() { + return N; + } + + /** + * 压入元素 + */ + public void push(Item item) { + Node oldfirst = first; + first = new Node(); + first.item = item; + first.next = oldfirst; + N++; + } + + /** + * 弹出元素 + */ + public Item pop() { + if (isEmpty()) throw new NoSuchElementException("Stack underflow"); + Item item = first.item; // 需弹出的元素 + first = first.next; // 删除头节点 + N--; + return item; + } + + + /** + * 返回但不弹出元素 + */ + public Item peek() { + if (isEmpty()) throw new NoSuchElementException("Stack underflow"); + return first.item; + } + + /** + * 从栈顶到栈底打印元素 + */ + public String toString() { + StringBuilder s = new StringBuilder(); + for (Item item : this) + s.append(item + " "); + return s.toString(); + } + + + /** + * 实现Iterable接口 + */ + public Iterator iterator() { + return new ListIterator(first); + } + + // 实现Iterator接口用于迭代,没有实现remove方法 + private class ListIterator implements Iterator { + private Node current; + + //初始化时,current指向栈顶 + public ListIterator(Node first) { + current = first; + } + + public boolean hasNext() { + return current != null; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public Item next() { + if (!hasNext()) throw new NoSuchElementException(); + Item item = current.item; + current = current.next; + return item; + } + } + + + /** + * 测试 + */ + public static void main(String[] args) { + Stack s = new Stack(); + while (!StdIn.isEmpty()) { + String item = StdIn.readString(); + if (!item.equals("-")) s.push(item); + else if (!s.isEmpty()) StdOut.print(s.pop() + " "); + } + StdOut.println("(" + s.size() + " left on stack)"); + } +} \ No newline at end of file