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
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
|