#ifndef QUICK_SORT_H
#define QUICK_SORT_H
#define QK_SORT
#include <iterator>
#include <cmath>
#include "INSERTION-SORT.h"
#ifdef _DEBUG
#include <iostream>
#endif // _DEBUG
//
// 算法思路:
// 每次都挑出一个数,并将比这个数小的数放在此数左边
// 将比这个数大的数都放在此数右边,于是一次划分就形成了
// 再递归的对划分出来的数组调用这个划分方法,知道结束;
// 而这个划分花费的时间为o(n);
// 如果每次都能大概划分为两个相等的序列,那么递归树的深度将是lgn
// 所以算法复杂度为nlg(n);
// 最差深度是n,所以最差的复杂度为n^2;这个最坏情况往往出现在排好序的序列上
//
template <typename T>
struct quick_sort_less
{
bool operator() (T lhs, T rhs)
{ return lhs < rhs;}
};
template <typename RandomAccessIterator, typename Val>
void swap_aux(RandomAccessIterator left, RandomAccessIterator right, Val*)
{
Val tmp = *left;
*left = *right;
*right = tmp;
}
template <typename RandomAccessIterator>
void swap(RandomAccessIterator lhs, RandomAccessIterator rhs)
{
if (lhs == rhs) return;
swap_aux(lhs, rhs, std::_Val_type(lhs));
}
template <typename RandomAccessIterator, typename Compare>
RandomAccessIterator quick_sort_partition(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
RandomAccessIterator ptr = first;
RandomAccessIterator index = first;
RandomAccessIterator key = last - 1;
for (; index != key; ++index)
{
if (comp(*index, *key))
{
swap(index, ptr++);
}
}
swap(index, ptr);
return ptr;
}
template <typename RandomAccessIterator, typename Compare>
void quick_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
if (last - first <= 1) return;
RandomAccessIterator mid = quick_sort_partition(first, last, comp);
#ifdef QK_SORT
std::cout << *mid << " " << mid - first << std::endl;
#endif // QK_SORT
quick_sort(first, mid++, comp);
quick_sort(mid, last, comp);
}
template <typename RandomAccessIterator, typename Compare>
RandomAccessIterator randomized_quick_sort_partition(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
RandomAccessIterator index = first;
RandomAccessIterator left_index = first;
RandomAccessIterator key_candidate = rand() % (last - first) + first;
RandomAccessIterator key = last - 1;
swap(key, key_candidate);
for (; index != last; ++index)
{
if (comp(*index, *key))
{
swap(left_index++, index);
}
}
swap(key, left_index);
return left_index;
}
template <typename RandomAccessIterator, typename Compare>
void randomized_quick_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
if (last - first <= 1) return;
RandomAccessIterator mid = randomized_quick_sort_partition(first, last, comp);
randomized_quick_sort(first, mid++, comp);
randomized_quick_sort(mid, last, comp);
}
template <typename RandomAccessIterator, typename Compare, typename _Size>
void _optimized_quick_sort_aux(RandomAccessIterator first, RandomAccessIterator last, Compare comp, _Size key_size)
{
if (last - first < key_size) return;
RandomAccessIterator mid = randomized_quick_sort_partition(first, last, comp);
_optimized_quick_sort_aux(first, mid++, comp, key_size);
_optimized_quick_sort_aux(mid, last, comp, key_size);
}
template <typename RandomAccessIterator, typename Compare, typename _Size>
void _optimized_quick_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp, _Size*)
{
// Get the key size where quick sort dont make effect
// when the array was divided into some kind of size
// that less than the key size (At that time, we use insertion sort
// to make this sort function more effective)
_Size key_size = std::log(_Size(last - first)) / std::log(2);
#ifdef QK_SORT
std::cout << key_size << std::endl;
#endif // QK_SORT
// Use quick sort do the pre-sort
_optimized_quick_sort_aux(first, last, comp, key_size);
// Use insertion sort do the latter sort
// Cause insertion is more effective while
// the array is nearly sorted
insertion_sort(first, last);
}
template <typename RandomAccessIterator, typename Compare>
void optimized_quick_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
_optimized_quick_sort(first, last, comp, std::_Dist_type(first));
}
#endif // QUICKSORT_H
【算法导论】快速排序实现
最新推荐文章于 2023-06-14 14:11:35 发布