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