Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

148 lines
3.2 KiB

//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
#ifndef TIER1_HEAP_SORT
#define TIER1_HEAP_SORT
template <typename T, typename LessThan>
inline bool IsHeap( T *pArr, int nCount, const LessThan &lessThan )
{
for ( int i = 1; i < nCount; ++i )
{
if ( lessThan( pArr[ ( i + 1 ) / 2 - 1 ], pArr[ i ] ) )
return false;
}
return true;
}
template <typename T, typename LessThan>
inline void HeapSort( T *pArr, int nCount, const LessThan &lessThan )
{
// heapify
for ( int nEndOfHeap = 1; nEndOfHeap < nCount; ++nEndOfHeap )
{
int nIdx = nEndOfHeap;
do
{
int nParent = ( nIdx + 1 ) / 2 - 1;
if ( lessThan( pArr[ nParent ], pArr[ nIdx ] ) )
{
Swap( pArr[ nParent ], pArr[ nIdx ] );
}
else
{
break;
}
nIdx = nParent;
}
while ( nIdx > 0 );
}
AssertDbg( IsHeap( pArr, nCount, lessThan ) );
// heap sort
for ( int nEndOfHeap = nCount; nEndOfHeap-- > 1; )
{
AssertDbg( !lessThan( pArr[ 0 ], pArr[ nEndOfHeap ] ) );
Swap( pArr[ 0 ], pArr[ nEndOfHeap ] );
// re-heapify the heap
int nIdx = 0;
for ( ;; )
{
int nChild = nIdx * 2 + 1;
if ( nChild >= nEndOfHeap )
break;
if ( nChild + 1 < nEndOfHeap )
{
// we have 2 children to compare against
if ( lessThan( pArr[ nChild ], pArr[ nChild + 1 ] ) )
{
nChild++; // always compare the root against the greater child
}
}
if ( lessThan( pArr[ nIdx ], pArr[ nChild ] ) )
{
Swap( pArr[ nIdx ], pArr[ nChild ] );
nIdx = nChild;
}
else
{
// the root is greater than any children now, we finished re-heapifying
break;
}
}
AssertDbg( IsHeap( pArr, nEndOfHeap, lessThan ) );
}
}
template <typename Array, typename LessThan>
inline void HeapSort( Array& arr, const LessThan &lessThan )
{
HeapSort( arr.Base( ), arr.Count( ), lessThan );
}
template <typename T, typename LessThan>
inline void BubbleSort( T *pArr, int nCount, const LessThan &lessThan )
{
for ( int i = 0; i + 1 < nCount; ++i )
{
for ( int j = i; j < nCount; ++j )
{
if ( lessThan( pArr[ j ], pArr[ i ] ) )
{
Swap( pArr[ j ], pArr[ i ] );
}
}
}
#ifdef DBGFLAG_ASSERT
for ( int i = 1; i < nCount; ++i )
{
Assert( lessThan( pArr[ i - 1 ], pArr[ i ] ) || !lessThan( pArr[ i ], pArr[ i - 1 ] ) );
}
#endif
}
/*
inline void HeapSortUnitTest( )
{
RandomSeed( 1 );
for ( uint i = 0; i < 100000; ++i )
{
CUtlVector< int >arr;
arr.SetCount( RandomInt( 0, 10000 ) );
for ( int j = 0; j < arr.Count( ); ++j )
arr[ j ] = RandomInt( 0, INT_MAX );
HeapSort( arr, [=] ( int a, int b ) ->bool { return a < b; } );
for ( int j = 1; j < arr.Count( ); ++j )
Assert( arr[ j - 1 ] <= arr[ j ] );
}
}
*/
template <typename Array>
inline void RemoveDuplicates( Array &arr )
{
// skip the first unique items
int nUniques = 1;
while ( nUniques < arr.Count( ) && !( arr[ nUniques ] == arr[ nUniques - 1 ] ) )
{
nUniques++;
}
if ( nUniques < arr.Count( ) )
{
// found the first duplicate; start copying unique items back
for ( int i = nUniques + 1; i < arr.Count( ); ++i )
{
if ( !( arr[ nUniques - 1 ] == arr[ i ] ) )
{
arr[ nUniques ] = arr[ i ]; // found another unique item
nUniques++;
}
}
arr.SetCountNonDestructively( nUniques );
}
}
#endif