2012-10-31 22:00:02 -04:00
|
|
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
|
|
|
// This file is part of the "Irrlicht Engine".
|
|
|
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
|
|
|
|
|
|
|
#ifndef __IRR_HEAPSORT_H_INCLUDED__
|
|
|
|
#define __IRR_HEAPSORT_H_INCLUDED__
|
|
|
|
|
|
|
|
#include "irrTypes.h"
|
|
|
|
|
|
|
|
namespace irr
|
|
|
|
{
|
|
|
|
namespace core
|
|
|
|
{
|
|
|
|
|
2016-12-11 00:21:17 -05:00
|
|
|
//! Function object which can be used for sorting (default)
|
2012-10-31 22:00:02 -04:00
|
|
|
template<class T>
|
2016-12-11 00:21:17 -05:00
|
|
|
inline bool sortless(const T& a, const T& b)
|
|
|
|
{
|
|
|
|
return a < b;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Sinks an element into the heap with a custom compare function
|
|
|
|
template<class T, class Compare>
|
|
|
|
inline void heapsink(T*array, s32 element, s32 max, Compare cmp)
|
2012-10-31 22:00:02 -04:00
|
|
|
{
|
|
|
|
while ((element<<1) < max) // there is a left child
|
|
|
|
{
|
|
|
|
s32 j = (element<<1);
|
|
|
|
|
2016-12-11 00:21:17 -05:00
|
|
|
if (j+1 < max && cmp(array[j], array[j+1]))
|
2012-10-31 22:00:02 -04:00
|
|
|
j = j+1; // take right child
|
|
|
|
|
2016-12-11 00:21:17 -05:00
|
|
|
if (cmp(array[element], array[j]))
|
2012-10-31 22:00:02 -04:00
|
|
|
{
|
|
|
|
T t = array[j]; // swap elements
|
|
|
|
array[j] = array[element];
|
|
|
|
array[element] = t;
|
|
|
|
element = j;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-11 00:21:17 -05:00
|
|
|
//! Sorts an array with size 'size' using heapsort with a custom compare function
|
|
|
|
template<class T, class Compare>
|
|
|
|
inline void heapsort(T* array_, s32 size, Compare cmp)
|
2012-10-31 22:00:02 -04:00
|
|
|
{
|
|
|
|
// for heapsink we pretent this is not c++, where
|
|
|
|
// arrays start with index 0. So we decrease the array pointer,
|
|
|
|
// the maximum always +2 and the element always +1
|
|
|
|
|
|
|
|
T* virtualArray = array_ - 1;
|
|
|
|
s32 virtualSize = size + 2;
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
// build heap
|
|
|
|
|
|
|
|
for (i=((size-1)/2); i>=0; --i)
|
2016-12-11 00:21:17 -05:00
|
|
|
heapsink(virtualArray, i+1, virtualSize-1, cmp);
|
2012-10-31 22:00:02 -04:00
|
|
|
|
|
|
|
// sort array, leave out the last element (0)
|
|
|
|
for (i=size-1; i>0; --i)
|
|
|
|
{
|
|
|
|
T t = array_[0];
|
|
|
|
array_[0] = array_[i];
|
|
|
|
array_[i] = t;
|
2016-12-11 00:21:17 -05:00
|
|
|
heapsink(virtualArray, 1, i + 1, cmp);
|
2012-10-31 22:00:02 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace core
|
|
|
|
} // end namespace irr
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|