1 50 package org.apache.avalon.excalibur.collections; 51 52 import java.util.Comparator ; 53 import java.util.NoSuchElementException ; 54 55 68 public final class BinaryHeap 69 implements PriorityQueue 70 { 71 private static final class MinComparator 72 implements Comparator 73 { 74 public final int compare( final Object lhs, final Object rhs ) 75 { 76 return ( (Comparable )lhs ).compareTo( rhs ); 77 } 78 } 79 80 private static final class MaxComparator 81 implements Comparator 82 { 83 public final int compare( final Object lhs, final Object rhs ) 84 { 85 return ( (Comparable )rhs ).compareTo( lhs ); 86 } 87 } 88 89 93 public static final Comparator MIN_COMPARATOR = new MinComparator(); 94 95 99 public static final Comparator MAX_COMPARATOR = new MaxComparator(); 100 101 private static final int DEFAULT_CAPACITY = 13; 102 private static final Comparator DEFAULT_COMPARATOR = MIN_COMPARATOR; 103 private int m_size; 104 private Object [] m_elements; 105 private Comparator m_comparator; 106 107 110 public BinaryHeap() 111 { 112 this( DEFAULT_CAPACITY, DEFAULT_COMPARATOR ); 113 } 114 115 120 public BinaryHeap( final int capacity ) 121 { 122 this( capacity, DEFAULT_COMPARATOR ); 123 } 124 125 131 public BinaryHeap( final Comparator comparator ) 132 { 133 this( DEFAULT_CAPACITY, comparator ); 134 } 135 136 143 public BinaryHeap( final int capacity, final Comparator comparator ) 144 { 145 m_elements = new Object [ capacity + 1 ]; 147 m_comparator = comparator; 148 } 149 150 156 public BinaryHeap( final boolean isMinHeap ) 157 { 158 this( DEFAULT_CAPACITY, isMinHeap ); 159 } 160 161 169 public BinaryHeap( final int capacity, final boolean isMinHeap ) 170 { 171 this( capacity, isMinHeap ? MIN_COMPARATOR : MAX_COMPARATOR ); 172 } 173 174 177 public void clear() 178 { 179 m_size = 0; 180 } 181 182 187 public boolean isEmpty() 188 { 189 return ( 0 == m_size ); 190 } 191 192 197 public boolean isFull() 198 { 199 return ( m_elements.length == m_size + 1 ); 201 } 202 203 208 public int size() 209 { 210 return m_size; 211 } 212 213 218 public void insert( final Object element ) 219 { 220 if( isFull() ) 221 { 222 grow(); 223 } 224 225 percolateUpHeap( element ); 226 } 227 228 234 public Object peek() throws NoSuchElementException 235 { 236 if( isEmpty() ) 237 { 238 throw new NoSuchElementException (); 239 } 240 else 241 { 242 return m_elements[ 1 ]; 243 } 244 } 245 246 252 public Object pop() throws NoSuchElementException 253 { 254 final Object result = peek(); 255 m_elements[ 1 ] = m_elements[ m_size-- ]; 256 257 m_elements[ m_size + 1 ] = null; 260 261 if( m_size != 0 ) 262 { 263 percolateDownHeap( 1 ); 264 } 265 266 return result; 267 } 268 269 274 private void percolateDownHeap( final int index ) 275 { 276 final Object element = m_elements[ index ]; 277 278 int hole = index; 279 int child = hole << 1; 280 281 while( child <= m_size ) 282 { 283 if( child != m_size && 286 m_comparator.compare( m_elements[ child + 1 ], m_elements[ child ] ) < 0 ) 287 { 288 child++; 289 } 290 291 if( m_comparator.compare( m_elements[ child ], element ) >= 0 ) 293 { 294 break; 295 } 296 297 m_elements[ hole ] = m_elements[ child ]; 298 hole = child; 299 child = hole << 1; 300 } 301 302 m_elements[ hole ] = element; 303 } 304 305 310 private void percolateUpHeap( final Object element ) 311 { 312 int hole = ++m_size; 313 int next = hole >> 1; 314 315 m_elements[ hole ] = element; 316 317 while( hole > 1 && 318 m_comparator.compare( element, m_elements[ next ] ) < 0 ) 319 { 320 m_elements[ hole ] = m_elements[ next ]; 321 hole = next; 322 next = hole >> 1; 323 } 324 325 m_elements[ hole ] = element; 326 } 327 328 331 private void grow() 332 { 333 final Object [] elements = 334 new Object [ m_elements.length * 2 ]; 335 System.arraycopy( m_elements, 0, elements, 0, m_elements.length ); 336 m_elements = elements; 337 } 338 339 345 public String toString() 346 { 347 final StringBuffer sb = new StringBuffer (); 348 349 sb.append( "[ " ); 350 351 for( int i = 1; i < m_size + 1; i++ ) 352 { 353 if( i != 1 ) 354 { 355 sb.append( ", " ); 356 } 357 sb.append( m_elements[ i ] ); 358 } 359 360 sb.append( " ]" ); 361 362 return sb.toString(); 363 } 364 } 365 366 | Popular Tags |