前言
许多基础数据类型都和对象的集合有关。具体来说,数据类型的值就是一组对象的集合,所有操作都是关于添加,删除或是访问集合中的对象。接下来,介绍三种数据类型,背包,队列,栈。语言是表达的载体,所以不可避免在表达算法时,依赖于语言的一些特性。
1 public class FixedCapacityStackOfStrings { 2 private String[] a; // holds the items 3 private int N; // number of items in stack 4 // create an empty stack with given capacity 5 public FixedCapacityStackOfStrings(int capacity) { 6 a = new String[capacity]; 7 N = 0; 8 } 9 public boolean isEmpty() { 10 return N == 0; 11 } 12 public boolean isFull() { 13 return N == a.length; 14 } 15 public void push(String item) { 16 a[N++] = item; 17 } 18 public String pop() { 19 return a[--N]; 20 } 21 public String peek() { 22 return a[N - 1]; 23 } 24 }
测试用例为:
1 public static void main(String[] args) { 2 Scanner in = new Scanner(System.in); 3 int max = in.nextInt(); 4 FixedCapacityStackOfStrings stack = new FixedCapacityStackOfStrings(max); 5 while (!StdIn.isEmpty()) { 6 String item = StdIn.readString(); 7 if (!item.equals("-")) 8 stack.push(item); 9 else if (stack.isEmpty()) 10 StdOut.println("BAD INPUT"); 11 else 12 StdOut.print(stack.pop() + " "); 13 } 14 StdOut.println(); 15 // print what's left on the stack 16 StdOut.print("Left on stack: "); 17 for (String s : stack) { 18 StdOut.print(s + " "); 19 } 20 StdOut.println(); 21 }
这种实现的主要性能特点是push和pop操作所需的时间独立于栈的长度。通俗来说就是和栈的长度无关,与数据的多少无关,这在操作许多数据时能极大节省时间。
1 /****************************************************************************** 2 * Compilation: javac FixedCapacityStackOfStrings.java 3 * Execution: java FixedCapacityStackOfStrings 4 * Dependencies: StdIn.java StdOut.java 5 * 6 * Stack of strings implementation with a fixed-size array. 7 * 8 * % more tobe.txt 9 * to be or not to - be - - that - - - is 10 * 11 * % java FixedCapacityStackOfStrings 5 < tobe.txt 12 * to be not that or be 13 * 14 * Remark: bare-bones implementation. Does not do repeated 15 * doubling or null out empty array entries to avoid loitering. 16 * 17 ******************************************************************************/ 18 19 import java.util.Iterator; 20 import java.util.NoSuchElementException; 21 22 public class FixedCapacityStackOfStrings implements Iterable<String> { 23 private String[] a; // holds the items 24 private int N; // number of items in stack 25 26 // create an empty stack with given capacity 27 public FixedCapacityStackOfStrings(int capacity) { 28 a = new String[capacity]; 29 N = 0; 30 } 31 32 public boolean isEmpty() { return N == 0; } 33 public boolean isFull() { return N == a.length; } 34 public void push(String item) { a[N++] = item; } 35 public String pop() { return a[--N]; } 36 public String peek() { return a[N-1]; } 37 public Iterator<String> iterator() { return new ReverseArrayIterator(); } 38 39 40 public class ReverseArrayIterator implements Iterator<String> { 41 private int i = N-1; 42 43 public boolean hasNext() { 44 return i >= 0; 45 } 46 47 public String next() { 48 if (!hasNext()) throw new NoSuchElementException(); 49 return a[i--]; 50 } 51 52 public void remove() { 53 throw new UnsupportedOperationException(); 54 } 55 } 56 57 58 public static void main(String[] args) { 59 int max = Integer.parseInt(args[0]); 60 FixedCapacityStackOfStrings stack = new FixedCapacityStackOfStrings(max); 61 while (!StdIn.isEmpty()) { 62 String item = StdIn.readString(); 63 if (!item.equals("-")) stack.push(item); 64 else if (stack.isEmpty()) StdOut.println("BAD INPUT"); 65 else StdOut.print(stack.pop() + " "); 66 } 67 StdOut.println(); 68 69 // print what's left on the stack 70 StdOut.print("Left on stack: "); 71 for (String s : stack) { 72 StdOut.print(s + " "); 73 } 74 StdOut.println(); 75 } 76 }
public class FixedCapacityStack<Item>
FixedCapacityStack<String> stack = new FixedCapacityStack<String>(max)
a = (Item[]) new Object[cap];
1 /****************************************************************************** 2 * Compilation: javac FixedCapacityStack.java 3 * Execution: java FixedCapacityStack 4 * Dependencies: StdIn.java StdOut.java 5 * 6 * Generic stack implementation with a fixed-size array. 7 * 8 * % more tobe.txt 9 * to be or not to - be - - that - - - is 10 * 11 * % java FixedCapacityStack 5 < tobe.txt 12 * to be not that or be 13 * 14 * Remark: bare-bones implementation. Does not do repeated 15 * doubling or null out empty array entries to avoid loitering. 16 * 17 ******************************************************************************/ 18 19 import java.util.Iterator; 20 import java.util.NoSuchElementException; 21 22 public class FixedCapacityStack<Item> implements Iterable<Item> { 23 private Item[] a; // holds the items 24 private int N; // number of items in stack 25 26 // create an empty stack with given capacity 27 public FixedCapacityStack(int capacity) { 28 a = (Item[]) new Object[capacity]; // no generic array creation 29 N = 0; 30 } 31 32 public boolean isEmpty() { return N == 0; } 33 public void push(Item item) { a[N++] = item; } 34 public Item pop() { return a[--N]; } 35 public Iterator<Item> iterator() { return new ReverseArrayIterator(); } 36 37 38 public class ReverseArrayIterator implements Iterator<Item> { 39 private int i = N-1; 40 41 public boolean hasNext() { 42 return i >= 0; 43 } 44 45 public Item next() { 46 if (!hasNext()) throw new NoSuchElementException(); 47 return a[i--]; 48 } 49 50 public void remove() { 51 throw new UnsupportedOperationException(); 52 } 53 } 54 55 56 public static void main(String[] args) { 57 int max = Integer.parseInt(args[0]); 58 FixedCapacityStack<String> stack = new FixedCapacityStack<String>(max); 59 while (!StdIn.isEmpty()) { 60 String item = StdIn.readString(); 61 if (!item.equals("-")) stack.push(item); 62 else if (stack.isEmpty()) StdOut.println("BAD INPUT"); 63 else StdOut.print(stack.pop() + " "); 64 } 65 StdOut.println(); 66 67 // print what's left on the stack 68 StdOut.print("Left on stack: "); 69 for (String s : stack) { 70 StdOut.print(s + " "); 71 } 72 StdOut.println(); 73 } 74 }
可和前面的没有泛型的代码对比理解。
1 /****************************************************************************** 2 * Compilation: javac ResizingArrayStack.java 3 * Execution: java ResizingArrayStack < input.txt 4 * Dependencies: StdIn.java StdOut.java 5 * Data files: http://algs4.cs.princeton.edu/13stacks/tobe.txt 6 * 7 * Stack implementation with a resizing array. 8 * 9 * % more tobe.txt 10 * to be or not to - be - - that - - - is 11 * 12 * % java ResizingArrayStack < tobe.txt 13 * to be not that or be (2 left on stack) 14 * 15 ******************************************************************************/ 16 17 import java.util.Iterator; 18 import java.util.NoSuchElementException; 19 20 /** 21 * The <tt>ResizingArrayStack</tt> class represents a last-in-first-out (LIFO) stack 22 * of generic items. 23 * It supports the usual <em>push</em> and <em>pop</em> operations, along with methods 24 * for peeking at the top item, testing if the stack is empty, and iterating through 25 * the items in LIFO order. 26 * <p> 27 * This implementation uses a resizing array, which double the underlying array 28 * when it is full and halves the underlying array when it is one-quarter full. 29 * The <em>push</em> and <em>pop</em> operations take constant amortized time. 30 * The <em>size</em>, <em>peek</em>, and <em>is-empty</em> operations takes 31 * constant time in the worst case. 32 * <p> 33 * For additional documentation, 34 * see <a href="http://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of 35 * <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 36 * 37 * @author Robert Sedgewick 38 * @author Kevin Wayne 39 */ 40 public class ResizingArrayStack<Item> implements Iterable<Item> { 41 private Item[] a; // array of items 42 private int N; // number of elements on stack 43 44 45 /** 46 * Initializes an empty stack. 47 */ 48 public ResizingArrayStack() { 49 a = (Item[]) new Object[2]; 50 N = 0; 51 } 52 53 /** 54 * Is this stack empty? 55 * @return true if this stack is empty; false otherwise 56 */ 57 public boolean isEmpty() { 58 return N == 0; 59 } 60 61 /** 62 * Returns the number of items in the stack. 63 * @return the number of items in the stack 64 */ 65 public int size() { 66 return N; 67 } 68 69 70 // resize the underlying array holding the elements 71 private void resize(int capacity) { 72 assert capacity >= N; 73 Item[] temp = (Item[]) new Object[capacity]; 74 for (int i = 0; i < N; i++) { 75 temp[i] = a[i]; 76 } 77 a = temp; 78 } 79 80 /** 81 * Adds the item to this stack. 82 * @param item the item to add 83 */ 84 public void push(Item item) { 85 if (N == a.length) resize(2*a.length); // double size of array if necessary 86 a[N++] = item; // add item 87 } 88 89 /** 90 * Removes and returns the item most recently added to this stack. 91 * @return the item most recently added 92 * @throws java.util.NoSuchElementException if this stack is empty 93 */ 94 public Item pop() { 95 if (isEmpty()) throw new NoSuchElementException("Stack underflow"); 96 Item item = a[N-1]; 97 a[N-1] = null; // to avoid loitering 98 N--; 99 // shrink size of array if necessary 100 if (N > 0 && N == a.length/4) resize(a.length/2); 101 return item; 102 } 103 104 105 /** 106 * Returns (but does not remove) the item most recently added to this stack. 107 * @return the item most recently added to this stack 108 * @throws java.util.NoSuchElementException if this stack is empty 109 */ 110 public Item peek() { 111 if (isEmpty()) throw new NoSuchElementException("Stack underflow"); 112 return a[N-1]; 113 } 114 115 /** 116 * Returns an iterator to this stack that iterates through the items in LIFO order. 117 * @return an iterator to this stack that iterates through the items in LIFO order. 118 */ 119 public Iterator<Item> iterator() { 120 return new ReverseArrayIterator(); 121 } 122 123 // an iterator, doesn't implement remove() since it's optional 124 private class ReverseArrayIterator implements Iterator<Item> { 125 private int i; 126 127 public ReverseArrayIterator() { 128 i = N-1; 129 } 130 131 public boolean hasNext() { 132 return i >= 0; 133 } 134 135 public void remove() { 136 throw new UnsupportedOperationException(); 137 } 138 139 public Item next() { 140 if (!hasNext()) throw new NoSuchElementException(); 141 return a[i--]; 142 } 143 } 144 145 146 /** 147 * Unit tests the <tt>Stack</tt> data type. 148 */ 149 public static void main(String[] args) { 150 ResizingArrayStack<String> s = new ResizingArrayStack<String>(); 151 while (!StdIn.isEmpty()) { 152 String item = StdIn.readString(); 153 if (!item.equals("-")) s.push(item); 154 else if (!s.isEmpty()) StdOut.print(s.pop() + " "); 155 } 156 StdOut.println("(" + s.size() + " left on stack)"); 157 } 158 }
1 public Item pop() { 2 if (isEmpty()) throw new NoSuchElementException("Stack underflow"); 3 Item item = a[N-1]; 4 a[N-1] = null; // to avoid loitering 5 N--; 6 // shrink size of array if necessary 7 if (N > 0 && N == a.length/4) resize(a.length/2); 8 return item; 9 }
1 a[N-1] = null; // to avoid loitering