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

//____________________________________________________________________________
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995 - 1996.
//
// File: HSort.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 5/3/1996 RaviR Created
//
//____________________________________________________________________________
#include "..\pch\headers.hxx"
#pragma hdrstop
#include "macros.h"
#include "jobidl.hxx"
#include <strSafe.h>
void PercolateUp(PJOBID *ppjid, UINT iMaxLevel);
void PercolateDown(PJOBID *ppjid, UINT iMaxLevel);
//
// HeapSort: HeapSort (also called TreeSort) works by calling
// PercolateUp and PercolateDown. PercolateUp organizes the elements
// into a "heap" or "tree," which has the properties shown below:
//
// element[1]
// / \
// element[2] element[3]
// / \ / \
// element[4] element[5] element[6] element[7]
// / \ / \ / \ / \
// ... ... ... ... ... ... ... ...
//
//
// Each "parent node" is greater than each of its "child nodes"; for
// example, element[1] is greater than element[2] or element[3];
// element[2] is greater than element[4] or element[5], and so forth.
// Therefore, once the first loop in HeapSort is finished, the
// largest element is in element[1].
//
// The second loop rebuilds the heap (with PercolateDown), but starts
// at the top and works down, moving the largest elements to the bottom.
// This has the effect of moving the smallest elements to the top and
// sorting the heap.
//
void hsort(PJOBID *ppjid, UINT cObjs)
{
//
// First build a "heap" with the largest element at the top
//
for (UINT i = 1; i < cObjs; i++)
{
PercolateUp(ppjid, i);
}
//
// The next loop rebuilds the heap (with PercolateDown), but starts
// at the top and works down, moving the largest elements to the bottom.
// This has the effect of moving the smallest elements to the top and
// sorting the heap.
//
PJOBID pjid;
for (i = cObjs - 1; i > 0; i--)
{
// Swap ppjid[0] & ppjid[i]
pjid = ppjid[0];
ppjid[0] = ppjid[i];
ppjid[i] = pjid;
PercolateDown(ppjid, i - 1);
}
}
inline int CompareJobIDs(PJOBID pjid1, PJOBID pjid2)
{
return lstrcmpi(pjid1->GetName(), pjid2->GetName());
}
// PercolateUp: Converts elements into a "heap" with the largest
// element at the top (see the diagram above).
void PercolateUp(PJOBID *ppjid, UINT iMaxLevel)
{
UINT i = iMaxLevel;
UINT iParent;
PJOBID pjid;
// Move the value in ppjid[iMaxLevel] up the heap until it has
// reached its proper node (that is, until it is greater than either
// of its child nodes, or until it has reached 1, the top of the heap).
while (i)
{
iParent = i / 2; // Get the subscript for the parent node
if (CompareJobIDs(ppjid[i], ppjid[iParent]) > 0)
{
// The value at the current node is bigger than the value at
// its parent node, so swap these two array elements.
// Swap ppjid[iParent], ppjid[i]
pjid = ppjid[iParent];
ppjid[iParent] = ppjid[i];
ppjid[i] = pjid;
i = iParent;
}
else
{
// Otherwise, the element has reached its proper place in the
// heap, so exit this procedure.
break;
}
}
}
// PercolateDown: Converts elements to a "heap" with the largest elements
// at the bottom. When this is done to a reversed heap (largest elements
// at top), it has the effect of sorting the elements.
//
void PercolateDown(PJOBID *ppjid, UINT iMaxLevel)
{
UINT iChild;
UINT i = 0;
PJOBID pjid;
// Move the value in ppjid[0] down the heap until it has reached
// its proper node (that is, until it is less than its parent node
// or until it has reached iMaxLevel, the bottom of the current heap).
while (1)
{
// Get the subscript for the child node.
iChild = 2 * i;
// Reached the bottom of the heap, so exit this procedure.
if (iChild > iMaxLevel)
{
break;
}
// If there are two child nodes, find out which one is bigger.
if (iChild + 1 <= iMaxLevel)
{
if (CompareJobIDs(ppjid[iChild + 1], ppjid[iChild]) > 0)
{
iChild++;
}
}
if (CompareJobIDs(ppjid[i], ppjid[iChild]) < 0)
{
// Move the value down since it is still not bigger than
// either one of its children.
// Swaps ppjid[i], ppjid[iChild]
pjid = ppjid[iChild];
ppjid[iChild] = ppjid[i];
ppjid[i] = pjid;
i = iChild;
}
else
{
// Otherwise, ppjid has been restored to a heap from 1 to
// iMaxLevel, so exit.
break;
}
}
}