KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > collections > TestBinaryHeap


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.collections;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.Arrays JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Comparator JavaDoc;
22 import java.util.NoSuchElementException JavaDoc;
23 import java.util.Random JavaDoc;
24
25 import junit.framework.Test;
26 import junit.framework.TestSuite;
27
28 import org.apache.commons.collections.collection.AbstractTestCollection;
29 import org.apache.commons.collections.comparators.ComparableComparator;
30 import org.apache.commons.collections.comparators.ReverseComparator;
31
32 /**
33  * Tests the BinaryHeap.
34  *
35  * @version $Revision: 1.16 $ $Date: 2004/02/18 01:20:35 $
36  *
37  * @author Michael A. Smith
38  */

39 public class TestBinaryHeap extends AbstractTestCollection {
40
41     public static Test suite() {
42         return new TestSuite(TestBinaryHeap.class);
43     }
44
45     public TestBinaryHeap(String JavaDoc testName) {
46         super(testName);
47     }
48
49     //-----------------------------------------------------------------------
50
public void verify() {
51         super.verify();
52         BinaryHeap heap = (BinaryHeap) collection;
53
54         Comparator JavaDoc c = heap.m_comparator;
55         if (c == null)
56             c = ComparatorUtils.naturalComparator();
57         if (!heap.m_isMinHeap)
58             c = ComparatorUtils.reversedComparator(c);
59
60         Object JavaDoc[] tree = heap.m_elements;
61         for (int i = 1; i <= heap.m_size; i++) {
62             Object JavaDoc parent = tree[i];
63             if (i * 2 <= heap.m_size) {
64                 assertTrue("Parent is less than or equal to its left child", c.compare(parent, tree[i * 2]) <= 0);
65             }
66             if (i * 2 + 1 < heap.m_size) {
67                 assertTrue("Parent is less than or equal to its right child", c.compare(parent, tree[i * 2 + 1]) <= 0);
68             }
69         }
70     }
71
72     //-----------------------------------------------------------------------
73
/**
74      * Overridden because UnboundedFifoBuffer isn't fail fast.
75      * @return false
76      */

77     public boolean isFailFastSupported() {
78         return false;
79     }
80
81     //-----------------------------------------------------------------------
82
public Collection JavaDoc makeConfirmedCollection() {
83         return new ArrayList JavaDoc();
84     }
85
86     public Collection JavaDoc makeConfirmedFullCollection() {
87         ArrayList JavaDoc list = new ArrayList JavaDoc();
88         list.addAll(Arrays.asList(getFullElements()));
89         return list;
90     }
91
92     /**
93      * Return a new, empty {@link Object} to used for testing.
94      */

95     public Collection JavaDoc makeCollection() {
96         return new BinaryHeap();
97     }
98
99     //-----------------------------------------------------------------------
100
public Object JavaDoc[] getFullElements() {
101         return getFullNonNullStringElements();
102     }
103
104     public Object JavaDoc[] getOtherElements() {
105         return getOtherNonNullStringElements();
106     }
107
108     //-----------------------------------------------------------------------
109
public void testBasicOps() {
110         BinaryHeap heap = new BinaryHeap();
111
112         assertTrue("heap should be empty after create", heap.isEmpty());
113
114         try {
115             heap.peek();
116             fail("NoSuchElementException should be thrown if peek is called before any elements are inserted");
117         } catch (NoSuchElementException JavaDoc e) {
118             // expected
119
}
120
121         try {
122             heap.pop();
123             fail("NoSuchElementException should be thrown if pop is called before any elements are inserted");
124         } catch (NoSuchElementException JavaDoc e) {
125             // expected
126
}
127
128         heap.insert("a");
129         heap.insert("c");
130         heap.insert("e");
131         heap.insert("b");
132         heap.insert("d");
133         heap.insert("n");
134         heap.insert("m");
135         heap.insert("l");
136         heap.insert("k");
137         heap.insert("j");
138         heap.insert("i");
139         heap.insert("h");
140         heap.insert("g");
141         heap.insert("f");
142
143         assertTrue("heap should not be empty after inserts", !heap.isEmpty());
144
145         for (int i = 0; i < 14; i++) {
146             assertEquals(
147                 "peek using default constructor should return minimum value in the binary heap",
148                 String.valueOf((char) ('a' + i)),
149                 heap.peek());
150
151             assertEquals(
152                 "pop using default constructor should return minimum value in the binary heap",
153                 String.valueOf((char) ('a' + i)),
154                 heap.pop());
155
156             if (i + 1 < 14) {
157                 assertTrue("heap should not be empty before all elements are popped", !heap.isEmpty());
158             } else {
159                 assertTrue("heap should be empty after all elements are popped", heap.isEmpty());
160             }
161         }
162
163         try {
164             heap.peek();
165             fail("NoSuchElementException should be thrown if peek is called after all elements are popped");
166         } catch (NoSuchElementException JavaDoc e) {
167             // expected
168
}
169
170         try {
171             heap.pop();
172             fail("NoSuchElementException should be thrown if pop is called after all elements are popped");
173         } catch (NoSuchElementException JavaDoc e) {
174             // expected
175
}
176     }
177
178     public void testBasicComparatorOps() {
179         BinaryHeap heap = new BinaryHeap(new ReverseComparator(new ComparableComparator()));
180
181         assertTrue("heap should be empty after create", heap.isEmpty());
182
183         try {
184             heap.peek();
185             fail("NoSuchElementException should be thrown if peek is called before any elements are inserted");
186         } catch (NoSuchElementException JavaDoc e) {
187             // expected
188
}
189
190         try {
191             heap.pop();
192             fail("NoSuchElementException should be thrown if pop is called before any elements are inserted");
193         } catch (NoSuchElementException JavaDoc e) {
194             // expected
195
}
196
197         heap.insert("a");
198         heap.insert("c");
199         heap.insert("e");
200         heap.insert("b");
201         heap.insert("d");
202         heap.insert("n");
203         heap.insert("m");
204         heap.insert("l");
205         heap.insert("k");
206         heap.insert("j");
207         heap.insert("i");
208         heap.insert("h");
209         heap.insert("g");
210         heap.insert("f");
211
212         assertTrue("heap should not be empty after inserts", !heap.isEmpty());
213
214         for (int i = 0; i < 14; i++) {
215
216             // note: since we're using a comparator that reverses items, the
217
// "minimum" item is "n", and the "maximum" item is "a".
218

219             assertEquals(
220                 "peek using default constructor should return minimum value in the binary heap",
221                 String.valueOf((char) ('n' - i)),
222                 heap.peek());
223
224             assertEquals(
225                 "pop using default constructor should return minimum value in the binary heap",
226                 String.valueOf((char) ('n' - i)),
227                 heap.pop());
228
229             if (i + 1 < 14) {
230                 assertTrue("heap should not be empty before all elements are popped", !heap.isEmpty());
231             } else {
232                 assertTrue("heap should be empty after all elements are popped", heap.isEmpty());
233             }
234         }
235
236         try {
237             heap.peek();
238             fail("NoSuchElementException should be thrown if peek is called after all elements are popped");
239         } catch (NoSuchElementException JavaDoc e) {
240             // expected
241
}
242
243         try {
244             heap.pop();
245             fail("NoSuchElementException should be thrown if pop is called after all elements are popped");
246         } catch (NoSuchElementException JavaDoc e) {
247             // expected
248
}
249     }
250     
251     /**
252      * Illustrates bad internal heap state reported in Bugzilla PR #235818.
253      */

254     public void testAddRemove() {
255         resetEmpty();
256         BinaryHeap heap = (BinaryHeap) collection;
257         heap.add(new Integer JavaDoc(0));
258         heap.add(new Integer JavaDoc(2));
259         heap.add(new Integer JavaDoc(4));
260         heap.add(new Integer JavaDoc(3));
261         heap.add(new Integer JavaDoc(8));
262         heap.add(new Integer JavaDoc(10));
263         heap.add(new Integer JavaDoc(12));
264         heap.add(new Integer JavaDoc(3));
265         confirmed.addAll(heap);
266         // System.out.println(heap);
267
Object JavaDoc obj = new Integer JavaDoc(10);
268         heap.remove(obj);
269         confirmed.remove(obj);
270         // System.out.println(heap);
271
verify();
272     }
273     
274     /**
275      * Generate heaps staring with Integers from 0 - heapSize - 1.
276      * Then perform random add / remove operations, checking
277      * heap order after modifications. Alternates minHeaps, maxHeaps.
278      *
279      * Based on code provided by Steve Phelps in PR #25818
280      *
281      */

282     public void testRandom() {
283         int iterations = 500;
284         int heapSize = 100;
285         int operations = 20;
286         Random JavaDoc randGenerator = new Random JavaDoc();
287         BinaryHeap h = null;
288         for(int i=0; i < iterations; i++) {
289             if (i < iterations / 2) {
290                 h = new BinaryHeap(true);
291             } else {
292                 h = new BinaryHeap(false);
293             }
294             for(int r = 0; r < heapSize; r++) {
295                 h.add( new Integer JavaDoc( randGenerator.nextInt(heapSize)) );
296             }
297             for( int r = 0; r < operations; r++ ) {
298                 h.remove(new Integer JavaDoc(r));
299                 h.add(new Integer JavaDoc(randGenerator.nextInt(heapSize)));
300             }
301             checkOrder(h);
302         }
303     }
304      
305     /**
306      * Pops all elements from the heap and verifies that the elements come off
307      * in the correct order. NOTE: this method empties the heap.
308      */

309     protected void checkOrder(BinaryHeap h) {
310         Integer JavaDoc lastNum = null;
311         Integer JavaDoc num = null;
312         boolean fail = false;
313         while (!h.isEmpty()) {
314             num = (Integer JavaDoc) h.pop();
315             if (h.m_isMinHeap) {
316                 assertTrue(lastNum == null || num.intValue() >= lastNum.intValue());
317             } else { // max heap
318
assertTrue(lastNum == null || num.intValue() <= lastNum.intValue());
319             }
320             lastNum = num;
321             num = null;
322         }
323     }
324     
325     /**
326      * Returns a string showing the contents of the heap formatted as a tree.
327      * Makes no attempt at padding levels or handling wrapping.
328      */

329     protected String JavaDoc showTree(BinaryHeap h) {
330         int count = 1;
331         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
332         for (int offset = 1; count < h.size() + 1; offset *= 2) {
333             for (int i = offset; i < offset * 2; i++) {
334                 if (i < h.m_elements.length && h.m_elements[i] != null)
335                     buffer.append(h.m_elements[i] + " ");
336                 count++;
337             }
338             buffer.append('\n');
339         }
340         return buffer.toString();
341     }
342
343 }
344
Popular Tags