Princeton Algorithms, Part I week2 stack&queue
stack&queue
stack:先进后出
queue:先进先出
首先是stack 有两种实现方式,第一种是用链表,第二种是用数组。
Stack: linked-list representation


stack: array implementation

上面这个实现是固定长度的array implementation
非常不方便,所以引入可变长度的实现
resizing-array implementation
那么以什么方式去可变呢?不能每次都capacity满了就加1,或者少了就减1,这种方式代价太大

正确的方式是当array满了以后,直接将数组的长度翻倍。
原因是

那么在缩减的时候该怎么缩减呢?
应该在当前array的1/4长度的时候再缩减而不是在1/2的时候,因为有一种极端情况就是,比如一共有8的长度,现在里面只有5个元素,pop出去一个,那么就需要缩减,然后又push进去,又要扩回8个,每次操作都是要访问N个元素 并且 赋值N个。下面是 java implementation
1 public class ResizingCapacityStackofString{ 2 3 private String [] s; 4 private int N = 0; 5 public ResizingCapacityStackofString(){ 6 7 s = new String[1]; 8 9 } 10 public ResizingCapacityStackofString(int capacity){ 11 12 s = new String[capacity]; 13 14 } 15 public boolean isEmpty(){ 16 return N == 0; 17 18 } 19 public void push(String item){ 20 if(N == s.length){resize(s.length * 2);} 21 s[N++] = item; 22 23 } 24 private void resize(int capacity){ 25 String[] newArr = new string[capacity]; 26 for(int i =0;i <N;i++){ 27 newArr[i] = s[i]; 28 } 29 s = newArr; 30 } 31 public String pop(){ 32 Strting item = s[N--]; 33 if(N <= 1/4 * s.length){resize(s.length/2);} 34 return item; 35 36 37 38 } 39 40 41 }
上面两种实现中 linked list based的stack的每一个操作都是常数时间,缺点是要花更多的空间和时间处理链表,而基于数组的stack 节省更多空间,但是在操作的时候会花更多的时间。
接下来是queue
首先也是以String的queue开头

enqueue只需要新的item直接插入在链表最后就行,dequeue只需要把首节点去掉。
Queue: linked-list implementation in Java

下面是基于resizing array 的实现

enqueue的时候就直接q[tail] = item dequeue就q[head] = item
resize就和stack的方式一样。
在实现的过程中我们可以用泛型去实现,避免了要写不同的数据类型的数据结构,并且通常在实现中,我们要给这个数据结构实现iterable接口,如下

如图,stack实现iterable接口并且实现了泛型,然后重写了iterator方法返回一个Iterator 我们再写一个内部类实现Iterator接口并且实现hasNext方法和next方法。
关于stack的应用很多,包括程序啊,左右括号的检查,还有逆波兰表达式等。
浙公网安备 33010602011771号