From ce87aa2973040ee2e498d134b98e562c84536cb6 Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Fri, 26 Oct 2018 11:36:36 +0800 Subject: [PATCH 1/3] [cpp][13_sorts] init. --- c-cpp/13_sorts/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 c-cpp/13_sorts/.gitkeep diff --git a/c-cpp/13_sorts/.gitkeep b/c-cpp/13_sorts/.gitkeep new file mode 100644 index 0000000..e69de29 From 558bd0ddb1c622e2394b601191c191fede099d6f Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Fri, 26 Oct 2018 12:31:31 +0800 Subject: [PATCH 2/3] [cpp][13_sorts] bucket_sort, done. --- c-cpp/13_sorts/bucket_sort.hpp | 43 ++++++++++++++++++++++++++++++ c-cpp/13_sorts/bucket_sort_test.cc | 33 +++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 c-cpp/13_sorts/bucket_sort.hpp create mode 100644 c-cpp/13_sorts/bucket_sort_test.cc diff --git a/c-cpp/13_sorts/bucket_sort.hpp b/c-cpp/13_sorts/bucket_sort.hpp new file mode 100644 index 0000000..41133ff --- /dev/null +++ b/c-cpp/13_sorts/bucket_sort.hpp @@ -0,0 +1,43 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/26. + */ + +#ifndef SORTS_BUCKET_SORT_HPP_ +#define SORTS_BUCKET_SORT_HPP_ + +#include +#include +#include +#include + +template ::value_type, + typename Compare = std::less> +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> 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_ + diff --git a/c-cpp/13_sorts/bucket_sort_test.cc b/c-cpp/13_sorts/bucket_sort_test.cc new file mode 100644 index 0000000..3199e8a --- /dev/null +++ b/c-cpp/13_sorts/bucket_sort_test.cc @@ -0,0 +1,33 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/26. + */ + +#include +#include +#include + +#include "bucket_sort.hpp" + +template > +void test_bucket_sort(Container cont, Compare comp = Compare()) { + bucket_sort(cont.begin(), cont.end(), comp); + std::transform(cont.begin(), cont.end(), std::ostream_iterator(std::cout, " "), + [](T i){ return i; }); + std::cout << std::endl; +} + +int main() { + std::vector 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; +} + From ce4ec5117ab1eb4ac04732e7ef04f3e92b4ebbed Mon Sep 17 00:00:00 2001 From: Liam Huang Date: Fri, 26 Oct 2018 15:48:44 +0800 Subject: [PATCH 3/3] [cpp][13_sorts] counting_sort, done. --- c-cpp/13_sorts/counting_sort.hpp | 40 ++++++++++++++++++++++++++++ c-cpp/13_sorts/counting_sort_test.cc | 36 +++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 c-cpp/13_sorts/counting_sort.hpp create mode 100644 c-cpp/13_sorts/counting_sort_test.cc diff --git a/c-cpp/13_sorts/counting_sort.hpp b/c-cpp/13_sorts/counting_sort.hpp new file mode 100644 index 0000000..5e7f782 --- /dev/null +++ b/c-cpp/13_sorts/counting_sort.hpp @@ -0,0 +1,40 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/26. + */ + +#ifndef SORTS_COUNTING_SORT_HPP_ +#define SORTS_COUNTING_SORT_HPP_ + +#include +#include +#include +#include + +template ::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 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 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_ + diff --git a/c-cpp/13_sorts/counting_sort_test.cc b/c-cpp/13_sorts/counting_sort_test.cc new file mode 100644 index 0000000..4e0814a --- /dev/null +++ b/c-cpp/13_sorts/counting_sort_test.cc @@ -0,0 +1,36 @@ +/** + * Created by Liam Huang (Liam0205) on 2018/10/26. + */ + +#include +#include +#include + +#include "counting_sort.hpp" + +template +void test_counting_sort(Container cont) { + counting_sort(cont.begin(), cont.end()); + std::transform(cont.begin(), cont.end(), std::ostream_iterator(std::cout, " "), + [](T i){ return i; }); + std::cout << std::endl; +} + +int main() { + // Liam Huang: pi for test + const std::vector test1{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3}; + const std::vector test2{2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9}; + const std::vector test3{5, 0, 2, 8, 8, 4, 1, 9, 7, 1, 6, 9, 3, 9, 9}; + const std::vector test4{3, 7, 5, 1, 0, 5, 8, 2, 0, 9, 7, 4, 9, 4, 4}; + const std::vector 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; +} +