Leaked source code of windows server 2003
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.

189 lines
5.3 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: HSort.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 5/3/1996 RaviR Created
  15. //
  16. //____________________________________________________________________________
  17. #include "..\pch\headers.hxx"
  18. #pragma hdrstop
  19. #include "macros.h"
  20. #include "jobidl.hxx"
  21. #include <strSafe.h>
  22. void PercolateUp(PJOBID *ppjid, UINT iMaxLevel);
  23. void PercolateDown(PJOBID *ppjid, UINT iMaxLevel);
  24. //
  25. // HeapSort: HeapSort (also called TreeSort) works by calling
  26. // PercolateUp and PercolateDown. PercolateUp organizes the elements
  27. // into a "heap" or "tree," which has the properties shown below:
  28. //
  29. // element[1]
  30. // / \
  31. // element[2] element[3]
  32. // / \ / \
  33. // element[4] element[5] element[6] element[7]
  34. // / \ / \ / \ / \
  35. // ... ... ... ... ... ... ... ...
  36. //
  37. //
  38. // Each "parent node" is greater than each of its "child nodes"; for
  39. // example, element[1] is greater than element[2] or element[3];
  40. // element[2] is greater than element[4] or element[5], and so forth.
  41. // Therefore, once the first loop in HeapSort is finished, the
  42. // largest element is in element[1].
  43. //
  44. // The second loop rebuilds the heap (with PercolateDown), but starts
  45. // at the top and works down, moving the largest elements to the bottom.
  46. // This has the effect of moving the smallest elements to the top and
  47. // sorting the heap.
  48. //
  49. void hsort(PJOBID *ppjid, UINT cObjs)
  50. {
  51. //
  52. // First build a "heap" with the largest element at the top
  53. //
  54. for (UINT i = 1; i < cObjs; i++)
  55. {
  56. PercolateUp(ppjid, i);
  57. }
  58. //
  59. // The next loop rebuilds the heap (with PercolateDown), but starts
  60. // at the top and works down, moving the largest elements to the bottom.
  61. // This has the effect of moving the smallest elements to the top and
  62. // sorting the heap.
  63. //
  64. PJOBID pjid;
  65. for (i = cObjs - 1; i > 0; i--)
  66. {
  67. // Swap ppjid[0] & ppjid[i]
  68. pjid = ppjid[0];
  69. ppjid[0] = ppjid[i];
  70. ppjid[i] = pjid;
  71. PercolateDown(ppjid, i - 1);
  72. }
  73. }
  74. inline int CompareJobIDs(PJOBID pjid1, PJOBID pjid2)
  75. {
  76. return lstrcmpi(pjid1->GetName(), pjid2->GetName());
  77. }
  78. // PercolateUp: Converts elements into a "heap" with the largest
  79. // element at the top (see the diagram above).
  80. void PercolateUp(PJOBID *ppjid, UINT iMaxLevel)
  81. {
  82. UINT i = iMaxLevel;
  83. UINT iParent;
  84. PJOBID pjid;
  85. // Move the value in ppjid[iMaxLevel] up the heap until it has
  86. // reached its proper node (that is, until it is greater than either
  87. // of its child nodes, or until it has reached 1, the top of the heap).
  88. while (i)
  89. {
  90. iParent = i / 2; // Get the subscript for the parent node
  91. if (CompareJobIDs(ppjid[i], ppjid[iParent]) > 0)
  92. {
  93. // The value at the current node is bigger than the value at
  94. // its parent node, so swap these two array elements.
  95. // Swap ppjid[iParent], ppjid[i]
  96. pjid = ppjid[iParent];
  97. ppjid[iParent] = ppjid[i];
  98. ppjid[i] = pjid;
  99. i = iParent;
  100. }
  101. else
  102. {
  103. // Otherwise, the element has reached its proper place in the
  104. // heap, so exit this procedure.
  105. break;
  106. }
  107. }
  108. }
  109. // PercolateDown: Converts elements to a "heap" with the largest elements
  110. // at the bottom. When this is done to a reversed heap (largest elements
  111. // at top), it has the effect of sorting the elements.
  112. //
  113. void PercolateDown(PJOBID *ppjid, UINT iMaxLevel)
  114. {
  115. UINT iChild;
  116. UINT i = 0;
  117. PJOBID pjid;
  118. // Move the value in ppjid[0] down the heap until it has reached
  119. // its proper node (that is, until it is less than its parent node
  120. // or until it has reached iMaxLevel, the bottom of the current heap).
  121. while (1)
  122. {
  123. // Get the subscript for the child node.
  124. iChild = 2 * i;
  125. // Reached the bottom of the heap, so exit this procedure.
  126. if (iChild > iMaxLevel)
  127. {
  128. break;
  129. }
  130. // If there are two child nodes, find out which one is bigger.
  131. if (iChild + 1 <= iMaxLevel)
  132. {
  133. if (CompareJobIDs(ppjid[iChild + 1], ppjid[iChild]) > 0)
  134. {
  135. iChild++;
  136. }
  137. }
  138. if (CompareJobIDs(ppjid[i], ppjid[iChild]) < 0)
  139. {
  140. // Move the value down since it is still not bigger than
  141. // either one of its children.
  142. // Swaps ppjid[i], ppjid[iChild]
  143. pjid = ppjid[iChild];
  144. ppjid[iChild] = ppjid[i];
  145. ppjid[i] = pjid;
  146. i = iChild;
  147. }
  148. else
  149. {
  150. // Otherwise, ppjid has been restored to a heap from 1 to
  151. // iMaxLevel, so exit.
  152. break;
  153. }
  154. }
  155. }