Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

PriorityQueue.h

Go to the documentation of this file.
00001 #ifndef MMANN_PRIORITY_QUEUE_H
00002 #define MMANN_PRIORITY_QUEUE_H
00003 
00011 
00012 #include "FCHelpingAlgorithms.h"
00013 
00015 template <class Data>
00016 class PriorityQueueElement
00017 {
00018 public:
00020     Data* m_Item;
00021 
00023     int m_Rating;
00024 };
00025 
00027 template <class Data>
00028 class PriorityQueue
00029 {
00030 public:
00032     PriorityQueue(int MaxElements, int MaxRating, int GrowBy, bool IsAscending);
00033 
00035     ~PriorityQueue();
00036 
00041     void Push(Data* Item, int Rating);
00042     
00046     Data* Pop();
00047 
00051     bool IsEmpty();
00052 
00053 private:
00055     int m_MaxSize;
00056 
00058     int m_CurrentSize;
00059 
00061     PriorityQueueElement<Data>* m_Elements; 
00062 
00064     int m_MaxRating;                        
00065 
00067     int m_GrowBy;                           
00068 
00070     bool m_IsAscendingHeap;                 
00071 };
00072 
00073 
00074 /* given an index to any element in a binary tree stored in a linear array with the root at 1 and 
00075    a "sentinel" value at 0 these macros are useful in making the code clearer */
00076 
00078 #define PQ_PARENT_INDEX(i) ((i)>>1)
00079 
00080 #define PQ_FIRST_ENTRY (1)
00081 
00083 #define PQ_LEFT_CHILD_INDEX(i) ((i)<<1)
00084 
00085 #define PQ_RIGHT_CHILD_INDEX(i) (((i)<<)+1)
00086 
00087 
00088 template <class Data>
00089 PriorityQueue<Data>::PriorityQueue(int MaxElements, int MaxRating, int GrowBy, bool IsAscending)
00090 {
00091     m_IsAscendingHeap = IsAscending;
00092     m_MaxSize = MaxElements;
00093     m_CurrentSize = 0;
00094     m_Elements = new PriorityQueueElement<Data>[m_MaxSize+1];
00095     m_GrowBy = GrowBy;
00096     m_MaxRating = MaxRating;
00097 }
00098 
00099 template <class Data>
00100 PriorityQueue<Data>::~PriorityQueue()
00101 {
00102     delete [] m_Elements;
00103 }
00104 
00105 template <class Data>
00106 void PriorityQueue<Data>::Push(Data* Item, int Rating)
00107 {   
00108     int i;
00109 
00110     if (m_CurrentSize == m_MaxSize )
00111     {
00112         int NewSize = m_MaxSize + m_GrowBy;
00113 
00114         Realloc<PriorityQueueElement<Data> >(&m_Elements, m_CurrentSize+1, NewSize+1);
00115 
00116         m_MaxSize = NewSize;
00117     }
00118 
00119 
00120     // set i to the first unused element and increment CurrentSize
00121     i = (m_CurrentSize += 1);
00122 
00123     /* while the parent of the space we're putting the new node into is worse than
00124        our new node, swap the space with the worse node. We keep doing that until we
00125        get to a worse node or until we get to the top
00126 
00127        note that we also can sort so that the minimum elements bubble up so we need to loops
00128        with the comparison operator flipped... */
00129 
00130     if(m_IsAscendingHeap)
00131     {
00132         while( ( i==PQ_FIRST_ENTRY ?
00133                  (m_MaxRating) /* return biggest possible rating if first element */
00134                  :
00135                  (m_Elements[ PQ_PARENT_INDEX(i) ].m_Rating )
00136                ) 
00137                < Rating 
00138              )
00139         {
00140             m_Elements[ i ] = m_Elements[ PQ_PARENT_INDEX(i) ];
00141 
00142             i = PQ_PARENT_INDEX(i);
00143         }
00144     }
00145     else
00146     {
00147         while( ( i==PQ_FIRST_ENTRY ?
00148                  (m_MaxRating) /* return biggest possible rating if first element */
00149                  :
00150                  (m_Elements[ PQ_PARENT_INDEX(i) ].m_Rating )
00151                ) 
00152                > Rating
00153              )
00154         {
00155             m_Elements[ i ] = m_Elements[ PQ_PARENT_INDEX(i) ];
00156 
00157             i = PQ_PARENT_INDEX(i);
00158         }
00159     }
00160 
00161     // then add the element at the space we created.
00162     m_Elements[i].m_Item = Item;
00163     m_Elements[i].m_Rating = Rating;
00164 }
00165 
00166 template <class Data>
00167 Data* PriorityQueue<Data>::Pop()
00168 {
00169     if (IsEmpty())
00170     {
00171         return NULL;
00172     }
00173 
00174     int i;
00175     int child;
00176 
00177     PriorityQueueElement<Data> pMaxElement = m_Elements[PQ_FIRST_ENTRY];
00178     //pointer to last element in tree
00179     PriorityQueueElement<Data> pLastElement = m_Elements[ m_CurrentSize-- ];
00180 
00181     if(m_IsAscendingHeap)
00182     {
00183 
00184         /* code to pop an element from an ascending (top to bottom) pqueue */
00185 
00186         /*  UNTESTED */
00187 
00188         for( i=PQ_FIRST_ENTRY; PQ_LEFT_CHILD_INDEX(i) <= m_CurrentSize; i=child )
00189         {
00190             /* set child to the smaller of the two children... */
00191 
00192             child = PQ_LEFT_CHILD_INDEX(i);
00193 
00194             if( (child != m_CurrentSize) &&
00195                 (m_Elements[child + 1].m_Rating > m_Elements[child].m_Rating) )
00196             {
00197                 child ++;
00198             }
00199 
00200             if( pLastElement.m_Rating < m_Elements[ child ].m_Rating )
00201             {
00202                 m_Elements[ i ] = m_Elements[ child ];
00203             }
00204             else
00205             {
00206                 break;
00207             }
00208         }
00209     }
00210     else
00211     {
00212         /* code to pop an element from a descending (top to bottom) pqueue */
00213 
00214         for( i=PQ_FIRST_ENTRY; PQ_LEFT_CHILD_INDEX(i) <= m_CurrentSize; i=child )
00215         {
00216             /* set child to the larger of the two children... */
00217 
00218             child = PQ_LEFT_CHILD_INDEX(i);
00219 
00220             if( (child != m_CurrentSize) &&
00221                 (m_Elements[child + 1].m_Rating < m_Elements[child].m_Rating) )
00222             {
00223                 child ++;
00224             }
00225 
00226             if(pLastElement.m_Rating > m_Elements[ child ].m_Rating )
00227             {
00228                 m_Elements[ i ] = m_Elements[ child ];
00229             }
00230             else
00231             {
00232                 break;
00233             }
00234         }
00235     }
00236 
00237     m_Elements[i] = pLastElement;
00238 
00239     return pMaxElement.m_Item;
00240 }
00241 
00242 template <class Data>
00243 bool PriorityQueue<Data>::IsEmpty()
00244 {
00245     if( m_CurrentSize == 0 )
00246     {
00247         return true;
00248     }
00249 
00250     return false;
00251 }
00252 
00253 #endif

Generated on Sat Nov 5 11:20:16 2005 for Cpp Freecell Solver by  doxygen 1.4.4