Merge pull request #109 from Liam0205/13_sorts

[cpp][13_sorts] 线性排序算法实现
This commit is contained in:
wangzheng0822 2018-11-02 10:45:32 +08:00 committed by GitHub
commit 9fdfde850f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 152 additions and 0 deletions

0
c-cpp/13_sorts/.gitkeep Normal file
View File

View File

@ -0,0 +1,43 @@
/**
* Created by Liam Huang (Liam0205) on 2018/10/26.
*/
#ifndef SORTS_BUCKET_SORT_HPP_
#define SORTS_BUCKET_SORT_HPP_
#include <iterator>
#include <functional>
#include <algorithm>
#include <vector>
template <size_t BucketSize,
typename IterT,
typename T = typename std::iterator_traits<IterT>::value_type,
typename Compare = std::less<T>>
void bucket_sort(IterT first, IterT last, Compare comp = Compare()) {
const T min = *std::min_element(first, last), max = *std::max_element(first, last);
const T range = max + 1 - min;
const size_t bucket_num = (range - 1) / BucketSize + 1;
std::vector<std::vector<T>> buckets(bucket_num);
for (auto b : buckets) {
b.reserve(2 * BucketSize);
}
for (IterT i = first; i != last; ++i) {
size_t idx = (*i - min) / BucketSize;
buckets[idx].emplace_back(*i);
}
IterT dest = first;
for (auto b : buckets) {
std::sort(b.begin(), b.end(), comp);
std::copy(b.begin(), b.end(), dest);
dest += b.size();
}
return;
}
#endif // SORTS_BUCKET_SORT_HPP_

View File

@ -0,0 +1,33 @@
/**
* Created by Liam Huang (Liam0205) on 2018/10/26.
*/
#include <iostream>
#include <vector>
#include <functional>
#include "bucket_sort.hpp"
template <size_t BucketSize,
typename Container,
typename T = typename Container::value_type,
typename Compare = std::less<T>>
void test_bucket_sort(Container cont, Compare comp = Compare()) {
bucket_sort<BucketSize>(cont.begin(), cont.end(), comp);
std::transform(cont.begin(), cont.end(), std::ostream_iterator<T>(std::cout, " "),
[](T i){ return i; });
std::cout << std::endl;
}
int main() {
std::vector<int> test{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9};
test_bucket_sort<2>(test); // 1 1 2 3 3 4 5 5 5 6 7 8 9 9 9
test_bucket_sort<3>(test); // 1 1 2 3 3 4 5 5 5 6 7 8 9 9 9
test_bucket_sort<4>(test); // 1 1 2 3 3 4 5 5 5 6 7 8 9 9 9
test_bucket_sort<5>(test); // 1 1 2 3 3 4 5 5 5 6 7 8 9 9 9
test_bucket_sort<6>(test); // 1 1 2 3 3 4 5 5 5 6 7 8 9 9 9
return 0;
}

View File

@ -0,0 +1,40 @@
/**
* Created by Liam Huang (Liam0205) on 2018/10/26.
*/
#ifndef SORTS_COUNTING_SORT_HPP_
#define SORTS_COUNTING_SORT_HPP_
#include <iterator>
#include <functional>
#include <algorithm>
#include <vector>
template <typename IterT,
typename T = typename std::iterator_traits<IterT>::value_type>
void counting_sort(IterT first, IterT last) {
const auto len = std::distance(first, last);
if (len < 2) { return; }
const T max = *std::max_element(first, last);
if (max == 0) { return; }
std::vector<size_t> counter(max + 1);
for (IterT i = first; i != last; ++i) {
++counter[*i];
}
for (size_t i = 1; i != max + 1; ++i) {
const size_t j = max - i;
counter[j] += counter[j + 1]; // Liam Huang: count of numbers that is not less than j.
}
std::vector<T> temp(len);
for (IterT i = first; i != last; ++i) {
temp[len - counter[*i]] = *i;
--counter[*i]; // Liam Huang: stable for relative position.
}
std::copy(temp.begin(), temp.end(), first);
}
#endif // SORTS_COUNTING_SORT_HPP_

View File

@ -0,0 +1,36 @@
/**
* Created by Liam Huang (Liam0205) on 2018/10/26.
*/
#include <iostream>
#include <vector>
#include <functional>
#include "counting_sort.hpp"
template <typename Container,
typename T = typename Container::value_type>
void test_counting_sort(Container cont) {
counting_sort(cont.begin(), cont.end());
std::transform(cont.begin(), cont.end(), std::ostream_iterator<T>(std::cout, " "),
[](T i){ return i; });
std::cout << std::endl;
}
int main() {
// Liam Huang: pi for test
const std::vector<int> test1{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3};
const std::vector<int> test2{2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9};
const std::vector<int> test3{5, 0, 2, 8, 8, 4, 1, 9, 7, 1, 6, 9, 3, 9, 9};
const std::vector<int> test4{3, 7, 5, 1, 0, 5, 8, 2, 0, 9, 7, 4, 9, 4, 4};
const std::vector<int> test5{5, 9, 2, 3, 0, 7, 8, 1, 6, 4, 0, 6, 2, 8, 6};
test_counting_sort(test1); // 1 1 2 3 3 3 4 5 5 5 6 7 8 9 9 9
test_counting_sort(test2); // 2 2 2 3 3 3 3 4 4 6 6 7 8 8 9
test_counting_sort(test3); // 0 1 1 2 3 4 5 6 7 8 8 9 9 9 9
test_counting_sort(test4); // 0 0 1 2 3 4 4 4 5 5 7 7 8 9 9
test_counting_sort(test5); // 0 0 1 2 2 3 4 5 6 6 6 7 8 8 9
return 0;
}