2010-11-20 10:37:14 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2009-06-15 06:50:47 +00:00
|
|
|
#ifndef TL_FILE_ALGORITHM_HPP
|
|
|
|
#define TL_FILE_ALGORITHM_HPP
|
2009-06-15 06:45:44 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "range.h"
|
2009-06-15 06:45:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
insert 4
|
|
|
|
v
|
|
|
|
1 2 3 4 5 6
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
template<class R, class T>
|
|
|
|
R partition_linear(R range, T value)
|
|
|
|
{
|
|
|
|
concept_empty::check(range);
|
|
|
|
concept_forwarditeration::check(range);
|
|
|
|
concept_sorted::check(range);
|
|
|
|
|
|
|
|
for(; !range.empty(); range.pop_front())
|
|
|
|
{
|
|
|
|
if(!(range.front() < value))
|
|
|
|
return range;
|
|
|
|
}
|
|
|
|
return range;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<class R, class T>
|
|
|
|
R partition_binary(R range, T value)
|
|
|
|
{
|
|
|
|
concept_empty::check(range);
|
|
|
|
concept_index::check(range);
|
|
|
|
concept_size::check(range);
|
|
|
|
concept_slice::check(range);
|
|
|
|
concept_sorted::check(range);
|
|
|
|
|
|
|
|
if(range.empty())
|
|
|
|
return range;
|
|
|
|
if(range.back() < value)
|
|
|
|
return R();
|
|
|
|
|
|
|
|
while(range.size() > 1)
|
|
|
|
{
|
|
|
|
unsigned pivot = (range.size()-1)/2;
|
|
|
|
if(range.index(pivot) < value)
|
|
|
|
range = range.slice(pivot+1, range.size()-1);
|
|
|
|
else
|
|
|
|
range = range.slice(0, pivot+1);
|
|
|
|
}
|
|
|
|
return range;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class R, class T>
|
|
|
|
R find_linear(R range, T value)
|
|
|
|
{
|
|
|
|
concept_empty::check(range);
|
|
|
|
concept_forwarditeration::check(range);
|
|
|
|
for(; !range.empty(); range.pop_front())
|
2010-05-29 07:25:38 +00:00
|
|
|
if(value == range.front())
|
2009-06-15 06:45:44 +00:00
|
|
|
break;
|
|
|
|
return range;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class R, class T>
|
|
|
|
R find_binary(R range, T value)
|
|
|
|
{
|
|
|
|
range = partition_linear(range, value);
|
|
|
|
if(range.empty()) return range;
|
|
|
|
if(range.front() == value) return range;
|
|
|
|
return R();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<class R>
|
|
|
|
void sort_bubble(R range)
|
|
|
|
{
|
|
|
|
concept_empty::check(range);
|
|
|
|
concept_forwarditeration::check(range);
|
|
|
|
concept_backwarditeration::check(range);
|
|
|
|
|
|
|
|
// slow bubblesort :/
|
|
|
|
for(; !range.empty(); range.pop_back())
|
|
|
|
{
|
|
|
|
R section = range;
|
|
|
|
typename R::type *prev = §ion.front();
|
|
|
|
section.pop_front();
|
|
|
|
for(; !section.empty(); section.pop_front())
|
|
|
|
{
|
|
|
|
typename R::type *cur = §ion.front();
|
|
|
|
if(*cur < *prev)
|
|
|
|
swap(*cur, *prev);
|
|
|
|
prev = cur;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
template<class R>
|
|
|
|
void sort_quick(R range)
|
|
|
|
{
|
|
|
|
concept_index::check(range);
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
template<class R>
|
|
|
|
void sort(R range)
|
|
|
|
{
|
|
|
|
sort_bubble(range);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<class R>
|
|
|
|
bool sort_verify(R range)
|
|
|
|
{
|
|
|
|
concept_empty::check(range);
|
|
|
|
concept_forwarditeration::check(range);
|
|
|
|
|
|
|
|
typename R::type *prev = &range.front();
|
|
|
|
range.pop_front();
|
|
|
|
for(; !range.empty(); range.pop_front())
|
|
|
|
{
|
|
|
|
typename R::type *cur = &range.front();
|
|
|
|
|
|
|
|
if(*cur < *prev)
|
|
|
|
return false;
|
|
|
|
prev = cur;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // TL_FILE_ALGORITHMS_HPP
|