Merge pull request #109 from Liam0205/13_sorts
[cpp][13_sorts] 线性排序算法实现
This commit is contained in:
commit
9fdfde850f
0
c-cpp/13_sorts/.gitkeep
Normal file
0
c-cpp/13_sorts/.gitkeep
Normal file
43
c-cpp/13_sorts/bucket_sort.hpp
Normal file
43
c-cpp/13_sorts/bucket_sort.hpp
Normal 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_
|
||||
|
33
c-cpp/13_sorts/bucket_sort_test.cc
Normal file
33
c-cpp/13_sorts/bucket_sort_test.cc
Normal 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;
|
||||
}
|
||||
|
40
c-cpp/13_sorts/counting_sort.hpp
Normal file
40
c-cpp/13_sorts/counting_sort.hpp
Normal 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_
|
||||
|
36
c-cpp/13_sorts/counting_sort_test.cc
Normal file
36
c-cpp/13_sorts/counting_sort_test.cc
Normal 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user