%PDF- %PDF-
| Direktori : /usr/include/boost/sort/heap_sort/ |
| Current File : //usr/include/boost/sort/heap_sort/heap_sort.hpp |
//----------------------------------------------------------------------------
/// @file heap_sort.hpp
/// @brief Insertion Sort algorithm
///
/// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n
/// Distributed under the Boost Software License, Version 1.0.\n
/// ( See accompanying file LICENSE_1_0.txt or copy at
/// http://www.boost.org/LICENSE_1_0.txt )
/// @version 0.1
///
/// @remarks
//-----------------------------------------------------------------------------
#ifndef __BOOST_SORT_INTROSORT_DETAIL_HEAP_SORT_HPP
#define __BOOST_SORT_INTROSORT_DETAIL_HEAP_SORT_HPP
#include <cassert>
#include <cstdint>
#include <iterator>
#include <stdexcept>
#include <utility> // for std::swap
#include <boost/sort/common/util/traits.hpp>
namespace boost
{
namespace sort
{
namespace heap_detail
{
namespace bscu = boost::sort::common::util;
//
//---------------------------------------------------------------------------
// struct : heap_sort
/// @brief : Heap sort algorithm
/// @remarks This algorithm is O(NLogN)
//---------------------------------------------------------------------------
template < class Iter_t, class Compare >
struct heap_sort
{
typedef bscu::value_iter<Iter_t> value_t;
//
//------------------------------------------------------------------------
// function : sort3
/// @brief Sort and signal the changes of three values
/// @param val_0 : first value to compare
/// @param val_1 : second value to compare
/// @param val_2 : third value to compare
/// @param [out] bool_0 : if true indicates val_0 had been changed
/// @param [out] bool_1 : if true indicates val_1 had been changed
/// @param [out] bool_2 : if true indicates val_2 had been changed
/// @return if true , some value had changed
/// @remarks
//------------------------------------------------------------------------
bool sort3 (value_t &val_0, value_t &val_1, value_t &val_2, bool &bool_0,
bool &bool_1, bool &bool_2)
{
bool_0 = bool_1 = bool_2 = false;
int value = 0;
if (val_0 < val_1) value += 4;
if (val_1 < val_2) value += 2;
if (val_0 < val_2) value += 1;
switch (value)
{
case 0: break;
case 2:
std::swap (val_1, val_2);
bool_1 = bool_2 = true;
break;
case 3:
if (not(val_0 > val_1)) {
std::swap (val_0, val_2);
bool_0 = bool_2 = true;
}
else
{
auto aux = std::move (val_2);
val_2 = std::move (val_1);
val_1 = std::move (val_0);
val_0 = std::move (aux);
bool_0 = bool_1 = bool_2 = true;
};
break;
case 4:
std::swap (val_0, val_1);
bool_0 = bool_1 = true;
break;
case 5:
if (val_1 > val_2) {
auto aux = std::move (val_0);
val_0 = std::move (val_1);
val_1 = std::move (val_2);
val_2 = std::move (aux);
bool_0 = bool_1 = bool_2 = true;
}
else
{
std::swap (val_0, val_2);
bool_0 = bool_2 = true;
};
break;
case 7:
std::swap (val_0, val_2);
bool_0 = bool_2 = true;
break;
default: abort ( );
};
return (bool_0 or bool_1 or bool_2);
};
//
//-----------------------------------------------------------------------
// function : make_heap
/// @brief Make the heap for to extract the sorted elements
/// @param first : iterator to the first element of the range
/// @param nelem : number of lements of the range
/// @param comp : object for to compare two elements
/// @remarks This algorithm is O(NLogN)
//------------------------------------------------------------------------
void make_heap (Iter_t first, size_t nelem, Compare comp)
{
size_t pos_father, pos_son;
Iter_t iter_father = first, iter_son = first;
bool sw = false;
for (size_t i = 1; i < nelem; ++i)
{
pos_father = i;
iter_father = first + i;
sw = false;
do
{
iter_son = iter_father;
pos_son = pos_father;
pos_father = (pos_son - 1) >> 1;
iter_father = first + pos_father;
if ((sw = comp (*iter_father, *iter_son)))
std::swap (*iter_father, *iter_son);
} while (sw and pos_father != 0);
};
};
//
//------------------------------------------------------------------------
// function : heap_sort
/// @brief : Heap sort algorithm
/// @param first: iterator to the first element of the range
/// @param last : iterator to the next element of the last in the range
/// @param comp : object for to do the comparison between the elements
/// @remarks This algorithm is O(NLogN)
//------------------------------------------------------------------------
heap_sort (Iter_t first, Iter_t last, Compare comp)
{
assert ((last - first) >= 0);
size_t nelem = last - first;
if (nelem < 2) return;
//--------------------------------------------------------------------
// Creating the initial heap
//--------------------------------------------------------------------
make_heap (first, nelem, comp);
//--------------------------------------------------------------------
// Sort the heap
//--------------------------------------------------------------------
size_t pos_father, pos_son;
Iter_t iter_father = first, iter_son = first;
bool sw = false;
for (size_t i = 1; i < nelem; ++i)
{
std::swap (*first, *(first + (nelem - i)));
pos_father = 0;
pos_son = 1;
iter_father = first;
sw = true;
while (sw and pos_son < (nelem - i))
{
// if the father have two sons must select the bigger
iter_son = first + pos_son;
if ((pos_son + 1) < (nelem - i) and
comp (*iter_son, *(iter_son + 1)))
{
++pos_son;
++iter_son;
};
if ((sw = comp (*iter_father, *iter_son)))
std::swap (*iter_father, *iter_son);
pos_father = pos_son;
iter_father = iter_son;
pos_son = (pos_father << 1) + 1;
};
};
};
}; // End class heap_sort
}; // end namespace heap_sort
namespace bscu = boost::sort::common::util;
template < class Iter_t, typename Compare = bscu::compare_iter < Iter_t > >
void heap_sort (Iter_t first, Iter_t last, Compare comp = Compare())
{
heap_detail::heap_sort<Iter_t, Compare> ( first, last, comp);
}
//
//****************************************************************************
}; // End namespace sort
}; // End namespace boost
//****************************************************************************
//
#endif