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.
 
 
 
 
 
 

191 lines
6.2 KiB

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2001 Microsoft Corporation
//
// Module Name:
// InsertionSort.h
//
// Description:
// This file contains templates to perform an insertion sort on an array.
//
// Documentation:
//
// Implementation Files:
// None.
//
// Maintained By:
// John Franco (jfranco) 1-JUN-2001
//
//////////////////////////////////////////////////////////////////////////////
// Make sure that this file is included only once per compile path.
#pragma once
//////////////////////////////////////////////////////////////////////////////
// Include Files
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Constant Declarations
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Template Declarations
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//++
//
// InsertionSort< Item, PredecessorFunction > template
//
// Description:
// InsertionSort(Start, Size, Precedes)
// reorders the array of Size elements beginning at Start so that
// for all p and q in [Start, Start + Size),
// Precedes(*p, *q) implies p < q.
//
// The notation [begin, end) refers to a half-open interval, so that
// for ( Item* pItem = begin; pItem < end; ++pItem )
// iterates through all elements in the array, and
// end - begin
// gives the number of elements in the array.
//
// Template Arguments:
// Item - the type of the elements in the array.
// requirements for Item:
// - copy constructor
// - assignment operator
//
// PredecessorFunction
// The function that determines whether one element should precede
// another in the sort order
//
// requirements for PredecessorFunction:
// - bool operator()( const Item &, const Item & ) const;
// or, PredecessorFunction can be a pointer to a function
// taking two Items and returning a bool.
//
// Function Arguments:
// pArrayStartIn
// A pointer to the first element of the array.
//
// cArraySizeIn
// The number of elements in the array.
//
// rPrecedesIn
// An instance of the predecessor function class, or a pointer to
// a function with the appropriate signature.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
template < class Item, class PredecessorFunction >
void
InsertionSort(
Item * pArrayStartIn
, size_t cArraySizeIn
, const PredecessorFunction & rPrecedesIn )
{
Assert( pArrayStartIn != NULL );
Item * pCurrentItem;
Item * pSortedLocation;
Item * pNextToCopy;
Item * pArrayEnd = pArrayStartIn + cArraySizeIn;
//
// Insertion sort algorithm; for a good description, see "Introduction to Algorithms"
// by Cormen, Leiserson, and Rivest.
//
//
// Loop invariant: all items to the left of pCurrentItem are in sorted order.
// Arrays of size zero or one are considered to be already sorted, so start
// pCurrentItem at second element in the array (if more than one element exists).
//
for ( pCurrentItem = pArrayStartIn + 1; pCurrentItem < pArrayEnd; ++pCurrentItem )
{
//
// Find where the current item needs to go to make the loop invariant true for pCurrentItem + 1.
// This could be a binary search, but collections of large enough size that it matters
// should use a quick sort instead.
//
pSortedLocation = pCurrentItem;
while ( ( pSortedLocation > pArrayStartIn )
&& rPrecedesIn( *pCurrentItem, *( pSortedLocation - 1 ) )
)
{
--pSortedLocation;
}
// Does the current item need to move?
if ( pSortedLocation != pCurrentItem )
{
// Store the current item.
Item tempItem( *pCurrentItem ); // declared inline to avoid requiring default constructor for Item
// Move all items in [pSortedLocation, pCurrentItem) to the right by one.
for ( pNextToCopy = pCurrentItem ; pNextToCopy > pSortedLocation; --pNextToCopy )
{
*pNextToCopy = *( pNextToCopy - 1 );
}
// Copy the current item into its proper location
*pSortedLocation = tempItem;
} // if item not in sorted location
} // for each item in array
} //*** InsertionSort
//////////////////////////////////////////////////////////////////////////////
//++
//
// LessThan<Item> and InsertionSort<Item> templates
//
// Description:
// These templates overload InsertionSort<Item, PredecessorFunction>
// to make PredecessorFunction use the less-than operator by default when
// the user provides no explicit predecessor function.
//
// Passing an instance of a function object allows the compiler to inline
// the comparison operation, which is impossible with a function pointer.
//
// Template parameters:
//
// Item - the type of the elements in the array.
// requirements for Item:
// - bool operator < ( const Item & ) const
// alternatively, Item can be a built-in type, like int
// - those from InsertionSort<Item, PredecessorFunction>
//
//--
//////////////////////////////////////////////////////////////////////////////
template < class Item >
struct LessThan
{
bool operator()( const Item & rLeftIn, const Item & rRightIn ) const
{
return ( rLeftIn < rRightIn );
}
};
template < class Item >
inline void
InsertionSort( Item * pBeginIn, size_t cArraySizeIn )
{
InsertionSort( pBeginIn, cArraySizeIn, LessThan< Item >() );
}