#ifndef UTLPRIORITYQUEUE_H #define UTLPRIORITYQUEUE_H #ifdef _WIN32 #pragma once #endif #include "utlvector.h" template< class T > class CUtlPriorityQueue { public: typedef bool (*LessFunc_t)(T const&, T const&); typedef T ElemType_t; CUtlPriorityQueue(int growSize = 0, int initSize = 0, LessFunc_t lessfunc = 0); CUtlPriorityQueue(T* pMemory, int numElements, LessFunc_t lessfunc = 0); inline T const& ElementAtHead() const { return m_heap.Element(0); } inline bool IsValidIndex(int index) { return m_heap.IsValidIndex(index); } void RemoveAtHead(); void RemoveAt(int index); void Insert(T const& element); void SetLessFunc(LessFunc_t func); inline int Count() const { return m_heap.Count(); } void RemoveAll() { m_heap.RemoveAll(); } void Purge() { m_heap.Purge(); } inline const T& Element(int index) const { return m_heap.Element(index); } protected: CUtlVector m_heap; void Swap(int index1, int index2); LessFunc_t m_LessFunc; }; template< class T > inline CUtlPriorityQueue::CUtlPriorityQueue(int growSize, int initSize, LessFunc_t lessfunc) : m_heap(growSize, initSize), m_LessFunc(lessfunc) { } template< class T > inline CUtlPriorityQueue::CUtlPriorityQueue(T* pMemory, int numElements, LessFunc_t lessfunc) : m_heap(pMemory, numElements), m_LessFunc(lessfunc) { } template void CUtlPriorityQueue::RemoveAtHead() { m_heap.FastRemove(0); int index = 0; int count = Count(); if (!count) return; int half = count / 2; int larger = index; while (index < half) { int child = ((index + 1) * 2) - 1; if (child < count) { if (m_LessFunc(m_heap[index], m_heap[child])) { larger = child; } } child++; if (child < count) { if (m_LessFunc(m_heap[larger], m_heap[child])) larger = child; } if (larger == index) break; Swap(index, larger); index = larger; } } template void CUtlPriorityQueue::RemoveAt(int index) { Assert(m_heap.IsValidIndex(index)); m_heap.FastRemove(index); int count = Count(); if (!count) return; int half = count / 2; int larger = index; while (index < half) { int child = ((index + 1) * 2) - 1; if (child < count) { if (m_LessFunc(m_heap[index], m_heap[child])) { larger = child; } } child++; if (child < count) { if (m_LessFunc(m_heap[larger], m_heap[child])) larger = child; } if (larger == index) break; Swap(index, larger); index = larger; } } template void CUtlPriorityQueue::Insert(T const& element) { int index = m_heap.AddToTail(); m_heap[index] = element; while (index != 0) { int parent = ((index + 1) / 2) - 1; if (m_LessFunc(m_heap[index], m_heap[parent])) break; Swap(parent, index); index = parent; } } template void CUtlPriorityQueue::Swap(int index1, int index2) { T tmp = m_heap[index1]; m_heap[index1] = m_heap[index2]; m_heap[index2] = tmp; } template void CUtlPriorityQueue::SetLessFunc(LessFunc_t lessfunc) { m_LessFunc = lessfunc; } #endif