下压栈
Created|Updated
|Post Views:
Introduction
栈的实现需要先了解几个背景:内存管理,接口继承,对象游离。
Detail
内存管理
java使得引用不可修改,而相对于其它语言来说增加了一条特性:自动内存管理
- 当引用a被覆盖时,那么引用a原来指向的对象就成了孤儿,就会被回收。
- 当对象离开作用域后也会被回收。
动态数组1 2 3 4 5 6 7
| private void resize(int max) { Item[] temp = (Item[]) new Object[max]; for(int i = 0; i < N; i++) temp[i] = a[i]; a = temp; }
|
对象游离
实现栈,主要的情景是:栈是占用使用数组的空间的。
当我们应用pop()的实现中,弹出的元素仍然在数组中。而java的自动内存管理是针对那些再也无法被引用的对象的内存,所有回收不到这些pop出去的元素。所以,就要采取一种方法:将元素的引用 设置为null,这将覆盖该引用,并使系统在用例用完后回收元素的内存。
1 2 3 4 5 6 7 8
| public Item pop() { Item item = a[--N]; a[N] = null; if(N > 0 && N == a.length / 4) resize(a.length / 2); return item; }
|
接口继承
- 一个类通过继承接口的方式,从而来继承接口的抽象方法。
- 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
接口的声明
接口(迭代)1 2 3 4
| public interface Iterable<Item> { Iterator<Item> iterator(); }
|
接口实现
...implements /*name*/[, 其他接口名称, 其他接口名称..., ...] ..
在其它类中实现接口1 2 3
| import java.util.Iterator;
public class ResizingArrayStack<Item> implements Iterable<Item>{
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public Iterator<Item> iterator() { return new ReverseArrayIterator(); } private class ReverseArrayIterator implements Iterator<Item> { private int i = N; public boolean hasNext() { return i > 0; } public Item next() { return a[--i]; } public void remove() {} }
|
Test
LIFO栈(动态数组)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
| import java.util.Iterator; public class ResizingArrayStack<Item> implements Iterable<Item>{ private Item[] a = (Item[])new Object[1]; private int N = 0; public boolean isEmpty() { return N == 0; } public int size() { return N; } private void resize(int max) { Item[] temp = (Item[]) new Object[max]; for(int i = 0; i < N; i++) temp[i] = a[i]; a = temp; } public void push(Item item) { if(N == a.length) resize(2 * a.length); a[N++] = item; } public Item pop() { Item item = a[--N]; a[N] = null; if(N > 0 && N == a.length / 4) resize(a.length / 2); return item; } public Iterator<Item> iterator() { return new ReverseArrayIterator(); } private class ReverseArrayIterator implements Iterator<Item> { private int i = N; public boolean hasNext() { return i > 0; } public Item next() { return a[--i]; } public void remove() {} } }
|
用例1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import edu.princeton.cs.algs4.StdIn; import edu.princeton.cs.algs4.StdOut;
public class Test {
public static void main(String[] args) { ResizingArrayStack<String> s = new ResizingArrayStack<String>(); 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)"); }
}
|