Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/media/mn8/util/cron/BinaryHeap.java


1   package org.media.mn8.util.cron;
2   
3   import java.util.Comparator;
4   import java.util.NoSuchElementException;
5   
6   
7   public final class BinaryHeap {
8       private static final class MinComparator implements Comparator {
9           public final int compare( final Object lhs, final Object rhs ) {
10              return ( (Comparable)lhs ).compareTo( rhs );
11          }
12      }
13  
14  
15      private static final class MaxComparator implements Comparator {
16          public final int compare( final Object lhs, final Object rhs ) {
17              return ( (Comparable)rhs ).compareTo( lhs );
18          }
19      }
20  
21  
22      public static final Comparator MIN_COMPARATOR = new MinComparator();
23      public static final Comparator MAX_COMPARATOR = new MaxComparator();
24      private static final int DEFAULT_CAPACITY = 13;
25      private static final Comparator DEFAULT_COMPARATOR = MIN_COMPARATOR;
26      private int m_size;
27      private Object[] m_elements;
28      private Comparator m_comparator;
29  
30  
31      public BinaryHeap() {
32          this( DEFAULT_CAPACITY, DEFAULT_COMPARATOR );
33      }
34  
35  
36      public BinaryHeap( final int capacity, final Comparator comparator ) {
37          //+1 as 0 is noop
38          m_elements = new Object[ capacity + 1 ];
39          m_comparator = comparator;
40      }
41  
42  
43      /**
44       * Clear all elements from queue.
45       */
46      public void clear() {
47          m_size = 0;
48      }
49  
50      /**
51       * Test if queue is empty.
52       *
53       * @return true if queue is empty else false.
54       */
55      public boolean isEmpty() {
56          return ( 0 == m_size );
57      }
58  
59  
60      /**
61       * Test if queue is full.
62       *
63       * @return true if queue is full else false.
64       */
65      public boolean isFull() {
66          //+1 as element 0 is noop
67          return ( m_elements.length == m_size + 1 );
68      }
69  
70  
71      /**
72       * Returns the number of elements currently on the heap.
73       *
74       * @return the size of the heap.
75       */
76      public int size() {
77          return m_size;
78      }
79  
80      /**
81       * Insert an element into queue.
82       *
83       * @param element the element to be inserted
84       */
85      public void insert( final Object element ) {
86          if( isFull() ) {
87              grow();
88          }
89          percolateUpHeap( element );
90      }
91  
92  
93      /**
94       * Return element on top of heap but don't remove it.
95       *
96       * @return the element at top of heap
97       * @throws NoSuchElementException if isEmpty() == true
98       */
99      public Object peek() throws NoSuchElementException {
100         if( isEmpty() ) {
101             throw new NoSuchElementException();
102         } else {
103             return m_elements[ 1 ];
104         }
105     }
106 
107 
108     /**
109      * Return element on top of heap and remove it.
110      *
111      * @return the element at top of heap
112      * @throws NoSuchElementException if isEmpty() == true
113      */
114     public Object pop() throws NoSuchElementException {
115         final Object result = peek();
116         m_elements[ 1 ] = m_elements[ m_size-- ];
117 
118         //set the unused element to 'null' so that the garbage collector
119         //can free the object if not used anywhere else.(remove reference)
120         m_elements[ m_size + 1 ] = null;
121 
122         if( m_size != 0 ) {
123             percolateDownHeap( 1 );
124         }
125         return result;
126     }
127 
128 
129     /**
130      * Percolate element down heap from top.
131      *
132      * @param element the element
133      */
134     private void percolateDownHeap( final int index ) {
135         final Object element = m_elements[ index ];
136 
137         int hole = index;
138         int child = hole << 1;
139 
140         while( child <= m_size ) {
141             //if we have a right child and that child can not be percolated
142             //up then move onto other child
143             if( child != m_size &&
144                 m_comparator.compare( m_elements[ child + 1 ], m_elements[ child ] ) < 0 )
145             {
146                 child++;
147             }
148 
149             //if we found resting place of bubble then terminate search
150             if( m_comparator.compare( m_elements[ child ], element ) >= 0 ) {
151                 break;
152             }
153 
154             m_elements[ hole ] = m_elements[ child ];
155             hole = child;
156             child = hole << 1;
157         }
158 
159         m_elements[ hole ] = element;
160     }
161 
162 
163     /**
164      * Percolate element up heap from bottom.
165      *
166      * @param element the element
167      */
168     private void percolateUpHeap( final Object element ) {
169         int hole = ++m_size;
170         int next = hole >> 1;
171 
172         m_elements[ hole ] = element;
173 
174         while( hole > 1 &&
175             m_comparator.compare( element, m_elements[ next ] ) < 0 )
176         {
177             m_elements[ hole ] = m_elements[ next ];
178             hole = next;
179             next = hole >> 1;
180         }
181 
182         m_elements[ hole ] = element;
183     }
184 
185 
186     /**
187      * Grows the heap by a factor of 2.
188      */
189     private void grow() {
190         final Object[] elements = new Object[ m_elements.length * 2 ];
191         System.arraycopy( m_elements, 0, elements, 0, m_elements.length );
192         m_elements = elements;
193     }
194 
195 
196     /**
197      * Create a string representing heap
198      * and all elements in heap.
199      *
200      * @return the string representing heap
201      */
202     public String toString() {
203         final StringBuffer sb = new StringBuffer();
204         sb.append( "[ " );
205         for( int i = 1; i < m_size + 1; i++ ) {
206             if( i != 1 ) {
207                 sb.append( ", " );
208             }
209             sb.append( m_elements[ i ] );
210         }
211         sb.append( " ]" );
212         return sb.toString();
213     }
214 }
215