www.pudn.com > GameEngine_src.rar > CPriorityQueue.h


#ifndef CPriorityQueue_h 
#define CPriorityQueue_h 
 
#include  
#include  
 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
class CPriorityQueue 
{ 
public: 
	CPriorityQueue(); 
	CPriorityQueue( int size ); 
	~CPriorityQueue(); 
 
	bool Init( int size ); 
	void Free(); 
 
	void Clear(); 
 
	bool Push( const T &t ); 
	bool Pop( T &t ); 
 
	T *GetPointer() { return m_queue; } 
	int GetLength() { return m_size + 1; } 
private: 
	int GetFather( int i ) { return (i - 1) >> 1; } 
	int GetSon1( int i ) { return (i << 1) + 1; } 
	int GetSon2( int i ) { return (i << 1) + 2; } 
 
private: 
	T	*m_queue; 
	int  m_max_size; 
	int  m_size; 
}; 
 
const int PQ_DEFAULT_SIZE = 128; 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
CPriorityQueue::CPriorityQueue() 
{ 
	m_queue = NULL; 
	m_size = -1; 
	m_max_size = 0; 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
CPriorityQueue::CPriorityQueue( int size ) 
{ 
	m_queue = NULL; 
	m_size = -1; 
	m_max_size = 0; 
 
	Init( size ); 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
CPriorityQueue::~CPriorityQueue() 
{ 
	Free(); 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
bool CPriorityQueue::Init( int size ) 
{ 
	if ( size < 4 ) 
		size = PQ_DEFAULT_SIZE; 
 
	m_queue = (T *)malloc( size * sizeof(T) ); 
	if ( m_queue == NULL ) 
		return false; 
 
	m_max_size = size; 
	return true; 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
void CPriorityQueue::Clear() 
{ 
	for ( int i = 0; i < m_size; ++i ) 
	{ 
		m_queue[i].~T(); 
	} 
	m_size = -1; 
} 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
void CPriorityQueue::Free() 
{ 
	Clear(); 
	free( m_queue ); 
	m_queue = NULL; 
	m_size = -1; 
	m_max_size = 0; 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
bool CPriorityQueue::Push( const T &t ) 
{ 
	if ( m_size + 1 < m_max_size ) 
	{ 
		++m_size; 
		new (&m_queue[m_size]) T; 
		m_queue[m_size] = t; 
 
		int index = m_size; 
		int father = GetFather( index ); 
 
		while( father >= 0 ) 
		{ 
			if ( m_queue[index] < m_queue[father] ) 
			{ 
				T temp = m_queue[index]; 
				m_queue[index] = m_queue[father]; 
				m_queue[father]= temp; 
 
				index = father; 
				father= GetFather( index ); 
			} 
			else 
				break; 
		} 
		return true; 
	} 
 
	return false; 
} 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
bool CPriorityQueue::Pop( T &t ) 
{ 
	if ( m_size >= 0 ) 
	{ 
		t = m_queue[0]; 
		 
		m_queue[0] = m_queue[m_size]; 
		m_queue[m_size].~T(); 
 
		int index = 0; 
		int son1 = GetSon1( 0 ); 
		int son2 = GetSon2( 0 ); 
 
		while( son1 < m_size && son2 < m_size ) 
		{ 
			int son = ( m_queue[son2] < m_queue[son1] ? son2 : son1 ); 
 
			if ( m_queue[son] < m_queue[index] ) 
			{ 
				T temp = m_queue[index]; 
				m_queue[index] = m_queue[son]; 
				m_queue[son] = temp; 
 
				index = son; 
				son1 = GetSon1( index ); 
				son2 = GetSon2( index ); 
			} 
			else 
				break; 
	 
		} 
 
		--m_size; 
		return true; 
	} 
 
	return false; 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
class CMaxHeap 
{ 
public: 
	CMaxHeap(); 
	CMaxHeap( int size ); 
	~CMaxHeap(); 
 
	bool Init( int size ); 
	void Free(); 
 
	void Clear(); 
 
	bool Push( const T &t ); 
	bool Pop( T &t ); 
 
	T *GetPointer() { return m_queue; } 
	int GetLength() { return m_size + 1; } 
private: 
	int GetFather( int i ) { return (i - 1) >> 1; } 
	int GetSon1( int i ) { return (i << 1) + 1; } 
	int GetSon2( int i ) { return (i << 1) + 2; } 
 
private: 
	T	*m_queue; 
	int  m_max_size; 
	int  m_size; 
}; 
 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
CMaxHeap::CMaxHeap() 
{ 
	m_queue = NULL; 
	m_size = -1; 
	m_max_size = 0; 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
CMaxHeap::CMaxHeap( int size ) 
{ 
	m_queue = NULL; 
	m_size = -1; 
	m_max_size = 0; 
 
	Init( size ); 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
CMaxHeap::~CMaxHeap() 
{ 
	Free(); 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
bool CMaxHeap::Init( int size ) 
{ 
	if ( size < 4 ) 
		size = PQ_DEFAULT_SIZE; 
 
	m_queue = (T *)malloc( size * sizeof(T) ); 
	if ( m_queue == NULL ) 
		return false; 
 
	m_max_size = size; 
	return true; 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
void CMaxHeap::Clear() 
{ 
	for ( int i = 0; i < m_size; ++i ) 
	{ 
		m_queue[i].~T(); 
	} 
 
	m_size = -1; 
} 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
void CMaxHeap::Free() 
{ 
	Clear(); 
	free( m_queue ); 
	m_queue = NULL; 
	m_size = -1; 
	m_max_size = 0; 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
bool CMaxHeap::Push( const T &t ) 
{ 
	if ( m_size + 1 < m_max_size ) 
	{ 
		++m_size; 
		new (&m_queue[m_size]) T; 
		m_queue[m_size] = t; 
 
		int index = m_size; 
		int father = GetFather( index ); 
 
		while( father >= 0 ) 
		{ 
			if ( Comp::less( m_queue[index] , m_queue[father] ) ) 
			{ 
				T temp = m_queue[index]; 
				m_queue[index] = m_queue[father]; 
				m_queue[father]= temp; 
 
				index = father; 
				father= GetFather( index ); 
			} 
			else 
				break; 
		} 
		return true; 
	} 
 
	return false; 
} 
 
///////////////////////////////////////////////////////////////////// 
// 
///////////////////////////////////////////////////////////////////// 
template 
bool CMaxHeap::Pop( T &t ) 
{ 
	if ( m_size >= 0 ) 
	{ 
		t = m_queue[0]; 
		 
		m_queue[0] = m_queue[m_size]; 
		m_queue[m_size].~T(); 
 
		int index = 0; 
		int son1 = GetSon1( 0 ); 
		int son2 = GetSon2( 0 ); 
 
		while( son1 < m_size && son2 < m_size ) 
		{ 
			int son = ( Comp::less( m_queue[son2] , m_queue[son1] ) ? son2 : son1 ); 
 
			if ( Comp::less( m_queue[son] , m_queue[index] ) ) 
			{ 
				T temp = m_queue[index]; 
				m_queue[index] = m_queue[son]; 
				m_queue[son] = temp; 
 
				index = son; 
				son1 = GetSon1( index ); 
				son2 = GetSon2( index ); 
			} 
			else 
				break; 
	 
		} 
 
		--m_size; 
		return true; 
	} 
 
	return false; 
} 
#endif