用數組實現棧


用數組表示棧

選擇用數組表示棧內容必須預先估計棧的最大容量。在Java中,數組一旦創建,其大小是無法改變的,而數組設置過大可能會浪費大量內存,設置過小又可能會溢出。

所以我們希望能夠動態調整數組a[i]的大小,使得它既足以保存所有元素,又不至於浪費過多的空間。

 

首先,實現一個方法將棧移動到另一個大小不同的數組中。

1 private void resize(int max) {
2         
3         Item[] temp = (Item[]) new Object[max];
4         for (int i = 0; i < N; i++) {
5             temp[i] = a[i];
6         }
7         a = temp;
8     }

 

 然后在push()中檢測數組是否太小。如果沒有多余的空間,就將數組的長度加倍。

 

1  public void push(Item item) {
2 
3         if (N == a.length) resize(2*a.length);    
4         a[N++] = item;                         
5 
6     }

 

 

類似的,在pop()中,先刪除棧頂元素,然后如果棧大小小於數組的四分之一就將數組的長度減半(這樣數組長度被減半之后約為半滿,在下次需要改變數組大小之前仍然能夠進行多次push()和pop()操作)。

 

1  public Item pop() {
2         
3         Item item = a[--N];
4         a[N] = null;                              //避免對象游離(見標注)
5        
6         if (N > 0 && N == a.length/4) resize(a.length/2);
7         return item;
8     }

 

 

 注:在對pop()的實現中,被彈出的元素的引用仍然存在於數組中。它永遠不會再被訪問了,但Java的垃圾回收集器無法知道這一點,除非該引用被覆蓋。這種情況(保存一個不需要的對象的引用)稱為游離。

在這里,只需將被彈出的數組元素的值設置為null即可。

 

 下面給出用數組表示棧的代碼實現:

   下壓(LIFO)棧(能夠動態調整數組大小的實現):

 

 1 public class ResizingArrayStack<Item> implements Iterable<Item> {
 2     private Item[] a;        
 3     private int N;           
 4 
 5     public ResizingArrayStack() {
 6         a = (Item[]) new Object[2];
 7         N = 0;
 8     }
 9 
10 
11     public boolean isEmpty() {
12         return N == 0;
13     }
14 
15 
16     public int size() {
17         return N;
18     }
19 
20 
21     private void resize(int capacity) {
22         assert capacity >= N;
23         Item[] temp = (Item[]) new Object[capacity];
24         for (int i = 0; i < N; i++) {
25             temp[i] = a[i];
26         }
27         a = temp;
28     }
29 
30 
31     public void push(Item item) {
32         if (N == a.length) resize(2*a.length);    
33         a[N++] = item;                            
34     }
35 
36     public Item pop() {
37         Item item = a[--N];
38         a[N] = null;                              
39 
40         if (N > 0 && N == a.length/4) resize(a.length/2);
41         return item;
42     }
43 
44 
45     public Item peek() {
46         return a[--N];
47     }
48 
49 
50     public Iterator<Item> iterator() {
51         return new ReverseArrayIterator();
52     }
53 
54     private class ReverseArrayIterator implements Iterator<Item> {
55         private int i;
56 
57         public ReverseArrayIterator() {
58             i = N;
59         }
60 
61         public boolean hasNext() {
62             return i >= 0;
63         }
64 
65         public void remove() {
66             throw new UnsupportedOperationException();
67         }
68 
69         public Item next() {
70             return a[--i];
71         }
72     }
73 
74 }

 

 

用數組表示棧的優點:

      每項操作的用時都與集合大小無關;

      空間需求總是不超過集合大小乘以一個常數。

用數組表示棧的缺點:

      某些push()和pop()操作會調整數組的大小:這項操作的耗時和棧大小成正比。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM