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