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

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. #ifndef TIER1_HEAP_SORT
  3. #define TIER1_HEAP_SORT
  4. template <typename T, typename LessThan>
  5. inline bool IsHeap( T *pArr, int nCount, const LessThan &lessThan )
  6. {
  7. for ( int i = 1; i < nCount; ++i )
  8. {
  9. if ( lessThan( pArr[ ( i + 1 ) / 2 - 1 ], pArr[ i ] ) )
  10. return false;
  11. }
  12. return true;
  13. }
  14. template <typename T, typename LessThan>
  15. inline void HeapSort( T *pArr, int nCount, const LessThan &lessThan )
  16. {
  17. // heapify
  18. for ( int nEndOfHeap = 1; nEndOfHeap < nCount; ++nEndOfHeap )
  19. {
  20. int nIdx = nEndOfHeap;
  21. do
  22. {
  23. int nParent = ( nIdx + 1 ) / 2 - 1;
  24. if ( lessThan( pArr[ nParent ], pArr[ nIdx ] ) )
  25. {
  26. Swap( pArr[ nParent ], pArr[ nIdx ] );
  27. }
  28. else
  29. {
  30. break;
  31. }
  32. nIdx = nParent;
  33. }
  34. while ( nIdx > 0 );
  35. }
  36. AssertDbg( IsHeap( pArr, nCount, lessThan ) );
  37. // heap sort
  38. for ( int nEndOfHeap = nCount; nEndOfHeap-- > 1; )
  39. {
  40. AssertDbg( !lessThan( pArr[ 0 ], pArr[ nEndOfHeap ] ) );
  41. Swap( pArr[ 0 ], pArr[ nEndOfHeap ] );
  42. // re-heapify the heap
  43. int nIdx = 0;
  44. for ( ;; )
  45. {
  46. int nChild = nIdx * 2 + 1;
  47. if ( nChild >= nEndOfHeap )
  48. break;
  49. if ( nChild + 1 < nEndOfHeap )
  50. {
  51. // we have 2 children to compare against
  52. if ( lessThan( pArr[ nChild ], pArr[ nChild + 1 ] ) )
  53. {
  54. nChild++; // always compare the root against the greater child
  55. }
  56. }
  57. if ( lessThan( pArr[ nIdx ], pArr[ nChild ] ) )
  58. {
  59. Swap( pArr[ nIdx ], pArr[ nChild ] );
  60. nIdx = nChild;
  61. }
  62. else
  63. {
  64. // the root is greater than any children now, we finished re-heapifying
  65. break;
  66. }
  67. }
  68. AssertDbg( IsHeap( pArr, nEndOfHeap, lessThan ) );
  69. }
  70. }
  71. template <typename Array, typename LessThan>
  72. inline void HeapSort( Array& arr, const LessThan &lessThan )
  73. {
  74. HeapSort( arr.Base( ), arr.Count( ), lessThan );
  75. }
  76. template <typename T, typename LessThan>
  77. inline void BubbleSort( T *pArr, int nCount, const LessThan &lessThan )
  78. {
  79. for ( int i = 0; i + 1 < nCount; ++i )
  80. {
  81. for ( int j = i; j < nCount; ++j )
  82. {
  83. if ( lessThan( pArr[ j ], pArr[ i ] ) )
  84. {
  85. Swap( pArr[ j ], pArr[ i ] );
  86. }
  87. }
  88. }
  89. #ifdef DBGFLAG_ASSERT
  90. for ( int i = 1; i < nCount; ++i )
  91. {
  92. Assert( lessThan( pArr[ i - 1 ], pArr[ i ] ) || !lessThan( pArr[ i ], pArr[ i - 1 ] ) );
  93. }
  94. #endif
  95. }
  96. /*
  97. inline void HeapSortUnitTest( )
  98. {
  99. RandomSeed( 1 );
  100. for ( uint i = 0; i < 100000; ++i )
  101. {
  102. CUtlVector< int >arr;
  103. arr.SetCount( RandomInt( 0, 10000 ) );
  104. for ( int j = 0; j < arr.Count( ); ++j )
  105. arr[ j ] = RandomInt( 0, INT_MAX );
  106. HeapSort( arr, [=] ( int a, int b ) ->bool { return a < b; } );
  107. for ( int j = 1; j < arr.Count( ); ++j )
  108. Assert( arr[ j - 1 ] <= arr[ j ] );
  109. }
  110. }
  111. */
  112. template <typename Array>
  113. inline void RemoveDuplicates( Array &arr )
  114. {
  115. // skip the first unique items
  116. int nUniques = 1;
  117. while ( nUniques < arr.Count( ) && !( arr[ nUniques ] == arr[ nUniques - 1 ] ) )
  118. {
  119. nUniques++;
  120. }
  121. if ( nUniques < arr.Count( ) )
  122. {
  123. // found the first duplicate; start copying unique items back
  124. for ( int i = nUniques + 1; i < arr.Count( ); ++i )
  125. {
  126. if ( !( arr[ nUniques - 1 ] == arr[ i ] ) )
  127. {
  128. arr[ nUniques ] = arr[ i ]; // found another unique item
  129. nUniques++;
  130. }
  131. }
  132. arr.SetCountNonDestructively( nUniques );
  133. }
  134. }
  135. #endif