├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bubble_sort.h ├── cocktail_sort.h ├── heap_sort.h ├── insertion_sort.h ├── introsort.detail.h ├── introsort.h ├── merge_sort.h ├── minmax_sort.h ├── quicksort.detail.h ├── quicksort.h ├── selection_sort.h ├── sort.h ├── sorting.VS2013.vcxproj ├── sorting.VS2013.vcxproj.filters ├── sorting.cpp └── sorting.sln /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | #ignore thumbnails created by windows 3 | Thumbs.db 4 | #Ignore files build by Visual Studio 5 | *.obj 6 | *.exe 7 | *.pdb 8 | *.user 9 | *.aps 10 | *.pch 11 | *.vspscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.cache 20 | *.ilk 21 | *.log 22 | [Bb]in 23 | [Dd]ebug*/ 24 | *.lib 25 | *.sbr 26 | obj/ 27 | [Rr]elease*/ 28 | _ReSharper*/ 29 | [Tt]est[Rr]esult* 30 | a.out 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Craig Henderson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # To build sorting algorithm suites 2 | CXX = g++ 3 | CXXFLAGS = -std=c++11 -g -Wall 4 | LDFLAGS= 5 | 6 | HEADERS=bubble_sort.h \ 7 | cocktail_sort.h \ 8 | heap_sort.h \ 9 | insertion_sort.h \ 10 | introsort.h \ 11 | merge_sort.h \ 12 | minmax_sort.h \ 13 | quicksort.h \ 14 | selection_sort.h 15 | SOURCES=sorting.cpp 16 | TARGET=sorting 17 | 18 | .PHONY : all clean 19 | 20 | all : $(SOURCES) $(HEADERS) 21 | $(CXX) $(CXXFLAGS) $(LDFLAGS) $(SOURCES) -o $(TARGET) 22 | 23 | clean : 24 | rm -f *.~ $(TARGET) 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #C++ Sorting Algorithm implementation 2 | 3 | A collection of Sorting Algorithm implemented in C++11. See the `develop` branch for latest version. 4 | 5 | ## Testing 6 | Tested on g++ 4.8.1 on Ubuntu 13.04 Server and Microsoft Visual Studio 2013RC 7 | 8 | ###Bubble Sort 9 | A slow a unuseful sorting algorithm for all but the simplest data sets, or for learning about sorting algorithms. 10 | 11 | |http://en.wikipedia.org/wiki/Bubble_sort|stable| 12 | |----|--- 13 | |Worst case performance |O(n^2) 14 | |Best case performance |O(n) 15 | |Average case performance |O(n^2) 16 | |Space |O(1) 17 | 18 | ###Cocktail Sort 19 | aka Bubble Sort, cocktail shaker sort, ripple sort, shuffle sort, shuttle sort or happy hour sort 20 | 21 | A Bubble sort variant which is only marginally more performant. Sorting is performed in both directions on each pass of the array. 22 | 23 | |http://en.wikipedia.org/wiki/Cocktail_sort|stable| 24 | |----|--- 25 | |Worst case performance |O(n^2) 26 | |Best case performance |O(n) 27 | |Average case performance |O(n^2) 28 | |Space |O(1) 29 | 30 | 31 | ###Heap Sort 32 | |http://en.wikipedia.org/wiki/Heapsort|unstable| 33 | |----|--- 34 | |Worst case performance |O(n log n) 35 | |Best case performance |Omega(n), O(n log n) 36 | |Average case performance |O(n log n) 37 | |Worst case space complexity |O(n) total, O(1) auxiliary 38 | 39 | ##Insertion Sort 40 | An adapted Bubble Sort that alternates between forward and backward passes. 41 | 42 | |http://en.wikipedia.org/wiki/Insertion_sort|stable| 43 | |----|---| 44 | |Worst case performance |O(n2) comparisons, swaps| 45 | |Best case performance |O(n) comparisons, O(1) swaps| 46 | |Average case performance |O(n2) comparisons, swaps| 47 | |Worst case space complexity |O(n) total, O(1)| 48 | 49 | ##Introsort 50 | Introsort is a hybrid sorting algorithm that uses Quick Sort to a recursion depth of O(log n) and then switches to a Heap Sort. Heap Sort is implemented using the standard C++ functions `make_heap` and `sort_heap`, both of which require Random Access data iterators. For maximum flexibility, this implementation of Introsort does not switch to Heap Sort if the data iterators are not Random Access, and can therefore operator on container with any iterator category. 51 | 52 | |http://en.wikipedia.org/wiki/Introsort|unstable| 53 | |----|---| 54 | |Worst case performance |O(n log n)| 55 | |Average case performance |O(n log n)| 56 | 57 | ###Merge Sort 58 | A divide and conquer recursive sorting algorithm which respects the original ordering of elements in the data set with identical keys. Two merge sort algorithms are included; 'merge_sort' an inplace sort that sorts a data set within itself, and a 'merge_sort_copy' which produces a secondary data set conatining the sorted result and leave the original unchanged. 59 | 60 | |http://en.wikipedia.org/wiki/Mergesort|stable| 61 | |----|--- 62 | |Worst case performance |O(n log n) 63 | |Best case performance |O(n log n) typical, O(n) natural variant 64 | |Average case performance |O(n log n) 65 | |Worst case space complexity |O(n) auxiliary 66 | 67 | ###Min Max Sort 68 | An adapted Selection Sort that finds and repositions the Min and Max elements on each pass. 69 | 70 | ||unstable| 71 | |----|--- 72 | |Worst case performance |O(n^2) 73 | |Best case performance |O(n) 74 | |Average case performance |O(n^2) 75 | |Space |O(1) 76 | 77 | ###Quick Sort 78 | A recursive sorting algorithm that works well with a cache, but is unstable; that is elements with identical keys may appear in a different order in the result than they do in the original data set. 79 | 80 | |http://en.wikipedia.org/wiki/Quicksort|unstable| 81 | |----|--- 82 | |Worst case performance |O(n2) (extremely rare) 83 | |Best case performance |O(n log n) 84 | |Average case performance |O(n log n) 85 | |Worst case space complexity |O(n) auxiliary (naive) O(log n) auxiliary (Sedgewick 1978) 86 | 87 | ###Selection Sort 88 | An inplace comparison sorting algorithm that is slow for large data sets, but it is a simple algorithm and has reasonable performance for inplace algorithms. 89 | 90 | |http://en.wikipedia.org/wiki/Selection_sort|stable| 91 | |----|--- 92 | |Worst case performance |O(n^2) 93 | |Best case performance |O(n^2) 94 | |Average case performance |O(n^2) 95 | |Space |O(1) 96 | -------------------------------------------------------------------------------- /bubble_sort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "sort.h" 5 | 6 | namespace cdmh { 7 | 8 | // Bubble Sort 9 | // Worst case performance O(n^2) 10 | // Best case performance O(n) 11 | // Average case performance O(n^2) 12 | // Wost case space complexity O(1) 13 | // http://en.wikipedia.org/wiki/Bubble_sort 14 | 15 | template::value_type>> 16 | inline void bubble_sort(It begin, It end, Pred pred=Pred()) 17 | { 18 | if (std::distance(begin, end) <= 1) 19 | return; 20 | 21 | auto ite = end; 22 | bool finished = false; 23 | while (!finished) 24 | { 25 | finished = true; 26 | std::advance(ite, -1); 27 | for (auto it=begin; it!=ite; ++it) 28 | { 29 | auto next = detail::advance(it, 1); 30 | if (pred(*next, *it)) 31 | { 32 | std::swap(*it, *next); 33 | finished = false; 34 | } 35 | } 36 | } 37 | } 38 | 39 | } // namespace cdmh 40 | 41 | // Permission is hereby granted, free of charge, to any person obtaining a copy 42 | // of this software and associated documentation files (the "Software"), to deal 43 | // in the Software without restriction, including without limitation the rights 44 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 45 | // copies of the Software, and to permit persons to whom the Software is 46 | // furnished to do so, subject to the following conditions: 47 | // 48 | // The above copyright notice and this permission notice shall be included in 49 | // all copies or substantial portions of the Software. 50 | // 51 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 52 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 53 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 54 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 55 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 56 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 57 | // THE SOFTWARE. 58 | -------------------------------------------------------------------------------- /cocktail_sort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "sort.h" 5 | 6 | namespace cdmh { 7 | 8 | // Cocktail Sort 9 | // a bidirectional bubble sort, with the same (slow) performance characteristics 10 | // Worst case performance O(n^2) 11 | // Best case performance O(n) 12 | // Average case performance O(n^2) 13 | // Wost case space complexity O(1) 14 | // http://en.wikipedia.org/wiki/Cocktail_sort 15 | 16 | template::value_type>> 17 | inline void cocktail_sort(It begin, It end, Pred pred=Pred()) 18 | { 19 | if (std::distance(begin, end) <= 1) 20 | return; 21 | 22 | bool finished = false; 23 | while (!finished) 24 | { 25 | // bubble sort forward iteration 26 | finished = true; 27 | std::advance(end, -1); 28 | for (auto it=begin; it!=end; ++it) 29 | { 30 | auto next = detail::advance(it, 1); 31 | if (pred(*next, *it)) 32 | { 33 | std::swap(*it, *next); 34 | finished = false; 35 | } 36 | } 37 | 38 | if (!finished) 39 | { 40 | // bubble sort backward iteration 41 | finished = true; 42 | std::advance(begin, 1); 43 | for (auto it =std::reverse_iterator(end), 44 | ite=std::reverse_iterator(begin); 45 | it!=ite; ++it) 46 | { 47 | auto next = detail::advance(it, 1); 48 | if (pred(*it, *next)) 49 | { 50 | std::swap(*it, *next); 51 | finished = false; 52 | } 53 | } 54 | } 55 | } 56 | } 57 | 58 | } // namespace cdmh 59 | 60 | // Permission is hereby granted, free of charge, to any person obtaining a copy 61 | // of this software and associated documentation files (the "Software"), to deal 62 | // in the Software without restriction, including without limitation the rights 63 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 64 | // copies of the Software, and to permit persons to whom the Software is 65 | // furnished to do so, subject to the following conditions: 66 | // 67 | // The above copyright notice and this permission notice shall be included in 68 | // all copies or substantial portions of the Software. 69 | // 70 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 71 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 72 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 73 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 74 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 75 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 76 | // THE SOFTWARE. 77 | -------------------------------------------------------------------------------- /heap_sort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #pragma once 5 | 6 | #include "sort.h" 7 | #include // make_heap 8 | 9 | namespace cdmh { 10 | 11 | // Heap Sort 12 | // Worst case performance O(n log n) 13 | // Best case performance Omega(n), O(n log n) 14 | // Average case performance O(n log n) 15 | // Worst case space complexity O(n) total, O(1) auxiliary 16 | // http://en.wikipedia.org/wiki/Heapsort 17 | 18 | template::value_type>> 19 | inline void heap_sort(It begin, It end, Pred pred=Pred()) 20 | { 21 | std::make_heap(begin, end, pred); 22 | std::sort_heap(begin, end, pred); 23 | } 24 | 25 | } // namespace cdmh 26 | 27 | // Permission is hereby granted, free of charge, to any person obtaining a copy 28 | // of this software and associated documentation files (the "Software"), to deal 29 | // in the Software without restriction, including without limitation the rights 30 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 31 | // copies of the Software, and to permit persons to whom the Software is 32 | // furnished to do so, subject to the following conditions: 33 | // 34 | // The above copyright notice and this permission notice shall be included in 35 | // all copies or substantial portions of the Software. 36 | // 37 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 43 | // THE SOFTWARE. 44 | -------------------------------------------------------------------------------- /insertion_sort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "sort.h" 5 | 6 | namespace cdmh { 7 | 8 | // Insertion Sort 9 | // Worst case performance О(n2) comparisons, swaps 10 | // Best case performance O(n) comparisons, O(1) swaps 11 | // Average case performance О(n2) comparisons, swaps 12 | // Worst case space complexity О(n) total, O(1) 13 | // http://en.wikipedia.org/wiki/Insertion_sort 14 | 15 | template::value_type>> 16 | inline void insertion_sort(It begin, It end, Pred pred=Pred()) 17 | { 18 | if (begin == end) 19 | return; 20 | 21 | for (auto it=begin; ++it != end; ) 22 | { 23 | auto it2 = it; 24 | auto value = std::move(*it); 25 | 26 | if (pred(value, *begin)) 27 | { 28 | std::move_backward(begin, it, ++it2); 29 | *begin = std::move(value); 30 | } 31 | else 32 | { 33 | for (auto first = it2; pred(value, *--first); it2=first) 34 | *it2 = std::move(*first); 35 | *it2 = std::move(value); 36 | } 37 | } 38 | } 39 | 40 | } // namespace cdmh 41 | 42 | // Permission is hereby granted, free of charge, to any person obtaining a copy 43 | // of this software and associated documentation files (the "Software"), to deal 44 | // in the Software without restriction, including without limitation the rights 45 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 46 | // copies of the Software, and to permit persons to whom the Software is 47 | // furnished to do so, subject to the following conditions: 48 | // 49 | // The above copyright notice and this permission notice shall be included in 50 | // all copies or substantial portions of the Software. 51 | // 52 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 53 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 54 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 55 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 56 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 57 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 58 | // THE SOFTWARE. 59 | -------------------------------------------------------------------------------- /introsort.detail.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "quicksort.detail.h" 5 | #include "heap_sort.h" 6 | 7 | namespace cdmh { 8 | 9 | namespace detail { 10 | 11 | // the heap sort uses std::make_heap and std::sort_heap, both of which only work with random access iterators. 12 | // this functor allows us to use heap_sort or not depending on the iterator type 13 | template::iterator_category, std::random_access_iterator_tag>::value> 14 | struct heap_sort_if_we_can 15 | { 16 | template 17 | bool operator()(Args...) 18 | { 19 | return false; 20 | } 21 | }; 22 | 23 | template 24 | struct heap_sort_if_we_can 25 | { 26 | template 27 | bool operator()(It begin, It end, Pred pred) 28 | { 29 | heap_sort(begin, end, pred); 30 | return true; 31 | } 32 | }; 33 | 34 | 35 | // detail introsort implementation takes a depth count 36 | template 37 | inline void introsort(It begin, It end, Pred pred, size_t depth) 38 | { 39 | auto const size = std::distance(begin, end); 40 | if (size <= 1) 41 | return; 42 | 43 | // if we've reached the depth limit, then attempt a heap sort. 44 | // if heap sort is not available to us, then continue with quicksort algorithm 45 | if (--depth == 0 && heap_sort_if_we_can()(begin, end, pred)) 46 | return; 47 | 48 | auto splits = detail::quicksort_splits(begin, end, pred); 49 | introsort(begin, splits.first, pred, depth); 50 | introsort(splits.second, end, pred, depth); 51 | } 52 | 53 | } // namespace detail 54 | 55 | } // namespace cdmh 56 | 57 | // Permission is hereby granted, free of charge, to any person obtaining a copy 58 | // of this software and associated documentation files (the "Software"), to deal 59 | // in the Software without restriction, including without limitation the rights 60 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 61 | // copies of the Software, and to permit persons to whom the Software is 62 | // furnished to do so, subject to the following conditions: 63 | // 64 | // The above copyright notice and this permission notice shall be included in 65 | // all copies or substantial portions of the Software. 66 | // 67 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 68 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 69 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 70 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 71 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 72 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 73 | // THE SOFTWARE. 74 | -------------------------------------------------------------------------------- /introsort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "sort.h" 5 | #include "introsort.detail.h" 6 | #include // floor, log 7 | 8 | namespace cdmh { 9 | 10 | // Introsort 11 | // Worst case performance O(n log n) 12 | // Average case performance O(n log n) 13 | // http://en.wikipedia.org/wiki/Introsort 14 | 15 | template::value_type>> 16 | inline void introsort(It begin, It end, Pred pred=Pred()) 17 | { 18 | if (std::distance(begin, end) > 1) 19 | detail::introsort(begin, end, pred, (size_t)floor(log(std::distance(begin,end)/log(2.0)))); 20 | } 21 | 22 | } // namespace cdmh 23 | 24 | // Permission is hereby granted, free of charge, to any person obtaining a copy 25 | // of this software and associated documentation files (the "Software"), to deal 26 | // in the Software without restriction, including without limitation the rights 27 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | // copies of the Software, and to permit persons to whom the Software is 29 | // furnished to do so, subject to the following conditions: 30 | // 31 | // The above copyright notice and this permission notice shall be included in 32 | // all copies or substantial portions of the Software. 33 | // 34 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 35 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 36 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 37 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 38 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 39 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 40 | // THE SOFTWARE. 41 | -------------------------------------------------------------------------------- /merge_sort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "sort.h" 5 | #include 6 | #include 7 | #include // inplace_merge 8 | 9 | namespace cdmh { 10 | 11 | // Merge Sort 12 | // Worst case performance O(n log n) 13 | // Best case performance O(n log n) typical, O(n) natural variant 14 | // Average case performance O(n log n) 15 | // Worst case space complexity O(n) auxiliary 16 | // http://en.wikipedia.org/wiki/Mergesort 17 | 18 | // inplace merge sort 19 | template::value_type>> 20 | inline void merge_sort(It begin, It end, Pred pred=Pred()) 21 | { 22 | auto const size = std::distance(begin, end); 23 | if (size <= 1) 24 | return; 25 | 26 | It middle = begin; 27 | std::advance(middle, size / 2); 28 | 29 | merge_sort(begin, middle, pred); 30 | merge_sort(middle, end, pred); 31 | std::inplace_merge(begin, middle, end, pred); 32 | } 33 | 34 | // merge sort to non-overlapping output iterator 35 | template::value_type>> 36 | inline void merge_sort_copy(It begin, It end, Out result, Pred pred=Pred()) 37 | { 38 | auto const size = std::distance(begin, end); 39 | if (size == 0) 40 | return; 41 | else if (size == 1) 42 | { 43 | *result++ = std::move(*begin); 44 | return; 45 | } 46 | 47 | It middle = begin; 48 | std::advance(middle, size / 2); 49 | 50 | std::vector::value_type> left, right; 51 | merge_sort_copy(begin, middle, std::back_inserter(left), pred); 52 | merge_sort_copy(middle, end, std::back_inserter(right), pred); 53 | std::merge(left.begin(), left.end(), right.begin(), right.end(), result, pred); 54 | } 55 | 56 | } // namespace cdmh 57 | 58 | // Permission is hereby granted, free of charge, to any person obtaining a copy 59 | // of this software and associated documentation files (the "Software"), to deal 60 | // in the Software without restriction, including without limitation the rights 61 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 62 | // copies of the Software, and to permit persons to whom the Software is 63 | // furnished to do so, subject to the following conditions: 64 | // 65 | // The above copyright notice and this permission notice shall be included in 66 | // all copies or substantial portions of the Software. 67 | // 68 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 69 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 70 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 71 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 72 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 73 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 74 | // THE SOFTWARE. 75 | -------------------------------------------------------------------------------- /minmax_sort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "sort.h" 5 | 6 | namespace cdmh { 7 | 8 | // MinMax Sort 9 | 10 | template::value_type>> 11 | inline void minmax_sort(It begin, It end, Pred pred=Pred()) 12 | { 13 | auto count = std::distance(begin, end); 14 | for (auto it=begin, ite=end; count > 1; ++it, count-=2) 15 | { 16 | auto minmax = std::minmax_element(it, ite, pred); 17 | std::advance(ite,-1); 18 | 19 | if (minmax.second == it && minmax.first == ite) 20 | std::swap(*it, *ite); 21 | else if (minmax.second == it) 22 | { 23 | std::swap(*minmax.second, *ite); 24 | std::swap(*minmax.first, *it); 25 | } 26 | else 27 | { 28 | std::swap(*minmax.first, *it); 29 | std::swap(*minmax.second, *ite); 30 | } 31 | } 32 | } 33 | 34 | } // namespace cdmh 35 | 36 | // Permission is hereby granted, free of charge, to any person obtaining a copy 37 | // of this software and associated documentation files (the "Software"), to deal 38 | // in the Software without restriction, including without limitation the rights 39 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 40 | // copies of the Software, and to permit persons to whom the Software is 41 | // furnished to do so, subject to the following conditions: 42 | // 43 | // The above copyright notice and this permission notice shall be included in 44 | // all copies or substantial portions of the Software. 45 | // 46 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 49 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 51 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 52 | // THE SOFTWARE. 53 | -------------------------------------------------------------------------------- /quicksort.detail.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #pragma once 5 | 6 | namespace cdmh { 7 | 8 | namespace detail { 9 | 10 | template 11 | inline T median(T const &t1, T const &t2, T const &t3) 12 | { 13 | if (t1 < t2) 14 | { 15 | if (t2 < t3) 16 | return t2; 17 | else if (t1 < t3) 18 | return t3; 19 | else 20 | return t1; 21 | } 22 | else if (t1 < t3) 23 | return t1; 24 | else if (t2 < t3) 25 | return t3; 26 | else 27 | return t2; 28 | } 29 | 30 | template 31 | inline std::pair quicksort_splits(It begin, It end, Pred pred) 32 | { 33 | using value_t = typename std::iterator_traits::value_type; 34 | using namespace std::placeholders; 35 | 36 | auto const not_pred = [&pred](value_t const &first, value_t const &second) { return !pred(second, first); }; 37 | auto const pivot = detail::median(*begin, *detail::advance(begin, std::distance(begin, end) / 2), *detail::advance(end, -1)); 38 | auto const split = std::partition(begin, end, std::bind(pred, _1, pivot)); 39 | return std::make_pair(split, std::partition(split, end, std::bind(not_pred, _1, pivot))); 40 | } 41 | 42 | } // namespace detail 43 | 44 | } // namespace cdmh 45 | 46 | // Permission is hereby granted, free of charge, to any person obtaining a copy 47 | // of this software and associated documentation files (the "Software"), to deal 48 | // in the Software without restriction, including without limitation the rights 49 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 50 | // copies of the Software, and to permit persons to whom the Software is 51 | // furnished to do so, subject to the following conditions: 52 | // 53 | // The above copyright notice and this permission notice shall be included in 54 | // all copies or substantial portions of the Software. 55 | // 56 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 57 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 58 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 59 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 60 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 61 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 62 | // THE SOFTWARE. 63 | -------------------------------------------------------------------------------- /quicksort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "sort.h" 5 | #include "quicksort.detail.h" 6 | 7 | namespace cdmh { 8 | 9 | // Quick Sort 10 | // Worst case performance O(n2) (extremely rare) 11 | // Best case performance O(n log n) 12 | // Average case performance O(n log n) 13 | // Worst case space complexity O(n) auxiliary (naive) O(log n) auxiliary (Sedgewick 1978) 14 | // http://en.wikipedia.org/wiki/Quicksort 15 | 16 | template::value_type>> 17 | inline void quicksort(It begin, It end, Pred pred=Pred()) 18 | { 19 | if (std::distance(begin, end) > 1) 20 | { 21 | auto splits = detail::quicksort_splits(begin, end, pred); 22 | quicksort(begin, splits.first, pred); 23 | quicksort(splits.second, end, pred); 24 | } 25 | } 26 | 27 | } // namespace cdmh 28 | 29 | // Permission is hereby granted, free of charge, to any person obtaining a copy 30 | // of this software and associated documentation files (the "Software"), to deal 31 | // in the Software without restriction, including without limitation the rights 32 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 33 | // copies of the Software, and to permit persons to whom the Software is 34 | // furnished to do so, subject to the following conditions: 35 | // 36 | // The above copyright notice and this permission notice shall be included in 37 | // all copies or substantial portions of the Software. 38 | // 39 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 40 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 41 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 42 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 43 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 44 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 45 | // THE SOFTWARE. 46 | -------------------------------------------------------------------------------- /selection_sort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "sort.h" 5 | 6 | namespace cdmh { 7 | 8 | // Selection Sort 9 | // Worst case performance О(n^2) 10 | // Best case performance О(n^2) 11 | // Average case performance О(n^2) 12 | // Worst case space complexity О(n) total, O(1) auxiliary 13 | // http://en.wikipedia.org/wiki/Selection_sort 14 | 15 | template::value_type>> 16 | inline void selection_sort(It begin, It end, Pred pred=Pred()) 17 | { 18 | for (auto it=begin; it!= end; ++it) 19 | std::swap(*std::min_element(it, end, pred), *it); 20 | } 21 | 22 | } // namespace cdmh 23 | 24 | // Permission is hereby granted, free of charge, to any person obtaining a copy 25 | // of this software and associated documentation files (the "Software"), to deal 26 | // in the Software without restriction, including without limitation the rights 27 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | // copies of the Software, and to permit persons to whom the Software is 29 | // furnished to do so, subject to the following conditions: 30 | // 31 | // The above copyright notice and this permission notice shall be included in 32 | // all copies or substantial portions of the Software. 33 | // 34 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 35 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 36 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 37 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 38 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 39 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 40 | // THE SOFTWARE. 41 | -------------------------------------------------------------------------------- /sort.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace cdmh { 9 | namespace detail { 10 | 11 | template 12 | inline It advance(It it, Distance n) 13 | { 14 | std::advance(it, n); 15 | return it; 16 | } 17 | 18 | } // namespace detail 19 | } // namespace cdmh 20 | 21 | // Permission is hereby granted, free of charge, to any person obtaining a copy 22 | // of this software and associated documentation files (the "Software"), to deal 23 | // in the Software without restriction, including without limitation the rights 24 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | // copies of the Software, and to permit persons to whom the Software is 26 | // furnished to do so, subject to the following conditions: 27 | // 28 | // The above copyright notice and this permission notice shall be included in 29 | // all copies or substantial portions of the Software. 30 | // 31 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 37 | // THE SOFTWARE. 38 | -------------------------------------------------------------------------------- /sorting.VS2013.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {45FC4B3A-675B-4B93-8CB0-94CCE965A6D7} 15 | Win32Proj 16 | insertion_sort 17 | sorting 18 | 19 | 20 | 21 | Application 22 | true 23 | v120 24 | Unicode 25 | 26 | 27 | Application 28 | false 29 | v120 30 | true 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | true 45 | 46 | 47 | false 48 | 49 | 50 | 51 | 52 | 53 | Level4 54 | Disabled 55 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 56 | true 57 | ProgramDatabase 58 | true 59 | 60 | 61 | Console 62 | true 63 | 64 | 65 | 66 | 67 | Level4 68 | 69 | 70 | Full 71 | true 72 | true 73 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 74 | false 75 | true 76 | AnySuitable 77 | Speed 78 | false 79 | StreamingSIMDExtensions2 80 | 81 | 82 | Console 83 | true 84 | true 85 | true 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /sorting.VS2013.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | 56 | 57 | Source Files 58 | 59 | 60 | -------------------------------------------------------------------------------- /sorting.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Craig Henderson 2 | // https://github.com/cdmh/sorting_algorithms 3 | 4 | #include "bubble_sort.h" 5 | #include "cocktail_sort.h" 6 | #include "heap_sort.h" 7 | #include "insertion_sort.h" 8 | #include "introsort.h" 9 | #include "merge_sort.h" 10 | #include "minmax_sort.h" 11 | #include "quicksort.h" 12 | #include "selection_sort.h" 13 | 14 | #include // is_sorted 15 | #include // greater 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace cdmh { 24 | namespace test { 25 | 26 | namespace utils { 27 | 28 | template 29 | C sorted(C container, Pred pred) 30 | { 31 | std::vector vector(container.begin(), container.end()); 32 | std::sort(vector.begin(), vector.end(), pred); 33 | return C(vector.begin(), vector.end()); 34 | } 35 | 36 | template 37 | void dump(It it, It ite) 38 | { 39 | for (; it!=ite; ++it) 40 | std::clog << " " << *it; 41 | } 42 | 43 | template 44 | bool const matching_containers(C const &container, C const &expected) 45 | { 46 | bool equal = true; 47 | size_t loop; 48 | auto it1 = container.begin(); 49 | auto it2 = expected.begin(); 50 | for (loop=0; equal && loop 75 | void sort_between_iterators(It it, It ite, Sort sort, Pred pred) 76 | { 77 | sort(it, ite, pred); 78 | std::clog << "--> "; 79 | utils::dump(it, ite); 80 | std::clog << '\n'; 81 | assert(std::is_sorted(it, ite, pred)); 82 | } 83 | 84 | template 85 | void sort_container(Sort sort, C container, Pred pred) 86 | { 87 | C expected(utils::sorted(container, pred)); 88 | sort(container.begin(), container.end(), pred); 89 | 90 | std::clog << "--> "; 91 | utils::dump(container.begin(), container.end()); 92 | std::clog << '\n'; 93 | 94 | assert(utils::matching_containers(container, expected)); 95 | } 96 | 97 | template 98 | void sort_container_copy(Sort sort, C container, Pred pred) 99 | { 100 | C result; 101 | C expected(utils::sorted(container, pred)); 102 | sort(container.begin(), container.end(), std::back_inserter(result), pred); 103 | 104 | std::clog << "--> "; 105 | utils::dump(result.begin(), result.end()); 106 | std::clog << '\n'; 107 | 108 | assert(utils::matching_containers(result, expected)); 109 | } 110 | 111 | } // namespace wrappers 112 | 113 | namespace algorithms { 114 | 115 | using ::cdmh::test::wrappers::sort_container; 116 | using ::cdmh::test::wrappers::sort_container_copy; 117 | 118 | template 119 | void bubble_sort(C container, Pred pred) 120 | { 121 | std::clog << "Bubble Sort " << container.size() << " elements \n"; 122 | sort_container( 123 | cdmh::bubble_sort::iterator, Pred>, 124 | std::vector(container.begin(), container.end()), 125 | pred); 126 | sort_container( 127 | cdmh::bubble_sort::iterator, Pred>, 128 | std::list(container.begin(), container.end()), 129 | pred); 130 | sort_container( 131 | cdmh::bubble_sort::iterator, Pred>, 132 | std::deque(container.begin(), container.end()), 133 | pred); 134 | 135 | // test the interface for default parameters 136 | std::random_shuffle(container.begin(), container.end()); 137 | cdmh::bubble_sort(container.begin(), container.end()); 138 | } 139 | 140 | template 141 | void cocktail_sort(C container, Pred pred) 142 | { 143 | std::clog << "Cocktail Sort " << container.size() << " elements \n"; 144 | sort_container( 145 | cdmh::cocktail_sort::iterator, Pred>, 146 | std::vector(container.begin(), container.end()), 147 | pred); 148 | sort_container( 149 | cdmh::cocktail_sort::iterator, Pred>, 150 | std::list(container.begin(), container.end()), 151 | pred); 152 | sort_container( 153 | cdmh::cocktail_sort::iterator, Pred>, 154 | std::deque(container.begin(), container.end()), 155 | pred); 156 | 157 | // test the interface for default parameters 158 | std::random_shuffle(container.begin(), container.end()); 159 | cdmh::cocktail_sort(container.begin(), container.end()); 160 | } 161 | 162 | template 163 | void heap_sort(C container, Pred pred) 164 | { 165 | // the heap sort currently uses std::make_heap and std::sort_heap which both require 166 | // a random access iterator, so only vector is tested here 167 | std::clog << "Heap Sort " << container.size() << " elements\n"; 168 | sort_container( 169 | cdmh::heap_sort::iterator, Pred>, 170 | std::vector(container.begin(), container.end()), 171 | pred); 172 | 173 | // test the interface for default parameters 174 | std::random_shuffle(container.begin(), container.end()); 175 | cdmh::heap_sort(container.begin(), container.end()); 176 | } 177 | 178 | template 179 | void insertion_sort(C container, Pred pred) 180 | { 181 | std::clog << "Insertion Sort " << container.size() << " elements\n"; 182 | sort_container( 183 | cdmh::insertion_sort::iterator, Pred>, 184 | std::vector(container.begin(), container.end()), 185 | pred); 186 | sort_container( 187 | cdmh::insertion_sort::iterator, Pred>, 188 | std::list(container.begin(), container.end()), 189 | pred); 190 | sort_container( 191 | cdmh::insertion_sort::iterator, Pred>, 192 | std::deque(container.begin(), container.end()), 193 | pred); 194 | 195 | // test the interface for default parameters 196 | std::random_shuffle(container.begin(), container.end()); 197 | cdmh::insertion_sort(container.begin(), container.end()); 198 | } 199 | 200 | template 201 | void introsort_sort(C container, Pred pred) 202 | { 203 | std::clog << "Introsort " << container.size() << " elements \n"; 204 | sort_container( 205 | cdmh::introsort::iterator, Pred>, 206 | std::vector(container.begin(), container.end()), 207 | pred); 208 | sort_container( 209 | cdmh::introsort::iterator, Pred>, 210 | std::list(container.begin(), container.end()), 211 | pred); 212 | sort_container( 213 | cdmh::introsort::iterator, Pred>, 214 | std::deque(container.begin(), container.end()), 215 | pred); 216 | 217 | // test the interface for default parameters 218 | std::random_shuffle(container.begin(), container.end()); 219 | cdmh::introsort(container.begin(), container.end()); 220 | } 221 | 222 | template 223 | void merge_sort_copy(C container, Pred pred) 224 | { 225 | std::clog << "Merge Sort (copy) " << container.size() << " elements\n"; 226 | sort_container_copy( 227 | cdmh::merge_sort_copy< 228 | typename std::vector::iterator, 229 | std::back_insert_iterator>, Pred>, 230 | std::vector(container.begin(), container.end()), 231 | pred); 232 | sort_container_copy( 233 | cdmh::merge_sort_copy< 234 | typename std::list::iterator, 235 | typename std::back_insert_iterator>, Pred>, 236 | std::list(container.begin(), container.end()), 237 | pred); 238 | sort_container_copy( 239 | cdmh::merge_sort_copy< 240 | typename std::deque::iterator, 241 | typename std::back_insert_iterator>, Pred>, 242 | std::deque(container.begin(), container.end()), 243 | pred); 244 | 245 | // test the interface for default parameters 246 | std::random_shuffle(container.begin(), container.end()); 247 | C result; 248 | cdmh::merge_sort_copy(container.begin(), container.end(), std::back_inserter(result)); 249 | } 250 | 251 | template 252 | void merge_sort(C container, Pred pred) 253 | { 254 | std::clog << "Merge Sort (inplace)" << container.size() << " elements\n"; 255 | sort_container( 256 | cdmh::merge_sort::iterator, Pred>, 257 | std::vector(container.begin(), container.end()), 258 | pred); 259 | sort_container( 260 | cdmh::merge_sort::iterator, Pred>, 261 | std::list(container.begin(), container.end()), 262 | pred); 263 | sort_container( 264 | cdmh::merge_sort::iterator, Pred>, 265 | std::deque(container.begin(), container.end()), 266 | pred); 267 | 268 | // test the interface for default parameters 269 | std::random_shuffle(container.begin(), container.end()); 270 | cdmh::merge_sort(container.begin(), container.end()); 271 | } 272 | 273 | template 274 | void minmax_sort(C container, Pred pred) 275 | { 276 | std::clog << "MinMax sort " << container.size() << " elements \n"; 277 | sort_container( 278 | cdmh::minmax_sort::iterator, Pred>, 279 | std::vector(container.begin(), container.end()), 280 | pred); 281 | sort_container( 282 | cdmh::minmax_sort::iterator, Pred>, 283 | std::list(container.begin(), container.end()), 284 | pred); 285 | sort_container( 286 | cdmh::minmax_sort::iterator, Pred>, 287 | std::deque(container.begin(), container.end()), 288 | pred); 289 | 290 | // test the interface for default parameters 291 | std::random_shuffle(container.begin(), container.end()); 292 | cdmh::minmax_sort(container.begin(), container.end()); 293 | } 294 | 295 | template 296 | void quicksort(C container, Pred pred) 297 | { 298 | std::clog << "Quicksort " << container.size() << " elements \n"; 299 | sort_container( 300 | cdmh::quicksort::iterator, Pred>, 301 | std::vector(container.begin(), container.end()), 302 | pred); 303 | sort_container( 304 | cdmh::quicksort::iterator, Pred>, 305 | std::list(container.begin(), container.end()), 306 | pred); 307 | sort_container( 308 | cdmh::quicksort::iterator, Pred>, 309 | std::deque(container.begin(), container.end()), 310 | pred); 311 | 312 | // test the interface for default parameters 313 | std::random_shuffle(container.begin(), container.end()); 314 | cdmh::quicksort(container.begin(), container.end()); 315 | } 316 | 317 | template 318 | void selection_sort(C container, Pred pred) 319 | { 320 | std::clog << "Selection sort " << container.size() << " elements \n"; 321 | sort_container( 322 | cdmh::selection_sort::iterator, Pred>, 323 | std::vector(container.begin(), container.end()), 324 | pred); 325 | sort_container( 326 | cdmh::selection_sort::iterator, Pred>, 327 | std::list(container.begin(), container.end()), 328 | pred); 329 | sort_container( 330 | cdmh::selection_sort::iterator, Pred>, 331 | std::deque(container.begin(), container.end()), 332 | pred); 333 | // test the interface for default parameters 334 | std::random_shuffle(container.begin(), container.end()); 335 | cdmh::selection_sort(container.begin(), container.end()); 336 | } 337 | 338 | } // namespace algorithms 339 | 340 | namespace drivers { 341 | 342 | namespace detail { 343 | 344 | template 345 | void shuffled_ints(int size, Fn fn) 346 | { 347 | std::vector container; 348 | for(int loop=0; loop 356 | void reversed_shuffled_ints(int size, Fn fn) 357 | { 358 | std::vector container; 359 | for (int i = 0; i < size; ++i) 360 | container.push_back((i+1) * 10); 361 | 362 | std::clog << "Sorting reversed shuffled pattern of " << size << " integers ... "; 363 | for (size_t n = 0; n < 100; ++n) 364 | { 365 | std::random_shuffle(container.begin(), container.end()); 366 | fn(container); 367 | } 368 | } 369 | 370 | template 371 | void sorted_ints(int size, Fn fn) 372 | { 373 | std::vector container; 374 | for (int i = 0; i < size; ++i) 375 | container.push_back((i+1) * 10); 376 | 377 | std::clog << "Sorting " << size << " sorted integers ... "; 378 | fn(container); 379 | } 380 | 381 | template 382 | void reversed_sorted_ints(size_t size, Fn fn) 383 | { 384 | std::vector container; 385 | for (size_t i = 0; i < size; ++i) 386 | container.push_back((size - i) * 10); 387 | 388 | std::clog << "Sorting " << size << " reverse-sorted integers ... "; 389 | fn(container); 390 | } 391 | 392 | template 393 | void partially_shuffled_ints(size_t size, Fn fn) 394 | { 395 | std::vector container; 396 | for (size_t i = 0; i < size; ++i) 397 | container.push_back((i+1) * 10); 398 | 399 | // sorted-shuffled-sorted pattern 400 | std::clog << "Sorting sorted-shuffled-sorted pattern of " << size << " integers ... "; 401 | for (size_t n = 0; n < 100; ++n) 402 | { 403 | std::random_shuffle(container.begin() + (size/3 * 1), container.begin() + (size/3 * 2)); 404 | fn(container); 405 | } 406 | 407 | // shuffled-sorted-shuffled pattern 408 | std::clog << "Sorting shuffled-sorted-shuffled pattern of " << size << " integers ... "; 409 | for (int n = 0; n < 100; ++n) 410 | { 411 | std::random_shuffle(container.begin() , container.begin() + (size/3 * 1)); 412 | std::random_shuffle(container.begin() + (size/3 * 2), container.end()); 413 | fn(container); 414 | } 415 | } 416 | 417 | template 418 | void test_sorts(C container, Pred pred) 419 | { 420 | // std::sort requires random access iterators, so list & deque are not supported 421 | std::clog << "std::sort " << container.size() << " elements\n"; 422 | [&pred](std::vector container) { 423 | wrappers::sort_between_iterators( 424 | container.begin(), 425 | container.end(), 426 | std::sort< 427 | typename std::vector::iterator, 428 | decltype(pred)>, 429 | pred); 430 | }(std::vector(container.begin(), container.end())); 431 | 432 | // std::stable_sort requires random access iterators, so list & deque are not supported 433 | std::clog << "std::stable_sort " << container.size() << " elements\n"; 434 | [&pred](std::vector container) { 435 | wrappers::sort_between_iterators( 436 | container.begin(), 437 | container.end(), 438 | std::stable_sort< 439 | typename std::vector::iterator, 440 | decltype(pred)>, 441 | pred); 442 | }(std::vector(container.begin(), container.end())); 443 | 444 | algorithms::bubble_sort(container, pred); 445 | algorithms::cocktail_sort(container, pred); 446 | algorithms::heap_sort(container, pred); 447 | algorithms::insertion_sort(container, pred); 448 | algorithms::introsort_sort(container, pred); 449 | algorithms::merge_sort(container, pred); 450 | algorithms::merge_sort_copy(container, pred); 451 | algorithms::minmax_sort(container, pred); 452 | algorithms::quicksort(container, pred); 453 | algorithms::selection_sort(container, pred); 454 | } 455 | 456 | } // namespace detail 457 | 458 | template 459 | void test_stable_sorts(C container, Pred pred) 460 | { 461 | std::clog << "Testing stability\n=================\n"; 462 | algorithms::bubble_sort(container, pred); 463 | algorithms::cocktail_sort(container, pred); 464 | algorithms::insertion_sort(container, pred); 465 | algorithms::merge_sort(container, pred); 466 | algorithms::merge_sort_copy(container, pred); 467 | } 468 | 469 | template 470 | void test_ascending_descending(C container) 471 | { 472 | // test sort ascending 473 | detail::test_sorts(container, std::less()); 474 | 475 | // test sort descending 476 | detail::test_sorts(container, std::greater()); 477 | } 478 | 479 | template 480 | void sized_test(int const size, Fn fn) 481 | { 482 | detail::shuffled_ints(size, fn); 483 | detail::reversed_shuffled_ints(size, fn); 484 | detail::sorted_ints(size, fn); 485 | detail::reversed_sorted_ints(size, fn); 486 | detail::partially_shuffled_ints(size, fn); 487 | } 488 | 489 | void run_exhaustive_tests(void) 490 | { 491 | // run exhaustive tests on arrays of these sizes 492 | std::vector sizes { 0, 1, 5, 30, 31, 32, 33, 128, 1023, 1024 }; 493 | for (auto size : sizes) 494 | { 495 | sized_test( 496 | size, 497 | std::bind( 498 | cdmh::test::algorithms::bubble_sort< 499 | std::vector, 500 | std::less>, 501 | std::placeholders::_1, 502 | std::less())); 503 | 504 | sized_test( 505 | size, 506 | std::bind( 507 | cdmh::test::algorithms::bubble_sort< 508 | std::vector, 509 | std::greater>, 510 | std::placeholders::_1, 511 | std::greater())); 512 | } 513 | } 514 | 515 | } // namespace drivers 516 | 517 | } // namespace test 518 | } // namespace cdmh 519 | 520 | int main() 521 | { 522 | using cdmh::test::drivers::run_exhaustive_tests; 523 | using cdmh::test::drivers::test_stable_sorts; 524 | using cdmh::test::drivers::test_ascending_descending; 525 | 526 | test_ascending_descending(std::vector{ 1, 2, 3, 4, 51, 2, 5, 6, 1, 6, 13, 1, 2, 3, 4, 5, 6, 14, 1, 2, 3, 4, 5, 6, 1 }); 527 | test_ascending_descending(std::vector{ "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" }); 528 | test_ascending_descending(std::vector{ "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" }); 529 | test_ascending_descending(std::vector{}); 530 | test_ascending_descending(std::vector{ 3 }); 531 | test_ascending_descending(std::vector{ 3, 4, 5, 9, 8, 2, 1, 7, 6 }); 532 | test_ascending_descending(std::vector{ 60, 10, 410, 40, 50, 60, 10, 40, 30, 40, 50, 60, 10, 40, 50, 6 }); 533 | test_ascending_descending(std::vector{ 10, 20, 30, 40, 510, 20, 50, 60, 10, 60, 130, 10, 20, 30, 40, 50, 60, 140, 10, 20, 30, 40, 50, 60, 1 }); 534 | 535 | // test stability of a sort algorithm by comparing doubles as ints 536 | test_stable_sorts( 537 | std::vector{ 1.2, 1.1, 0.4, 0.1, 0.9, 3.1, 3.6, 9.4, 9.8, 9.6, 3.2 }, 538 | [](double const &first, double const &second) { 539 | return int(first){ 544 | "Lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", "Praesent", "a", "posuere", 545 | "lorem", "Nam", "porttitor", "viverra", "nisl", "ac", "adipiscing", "tortor", "ornare", "vel", "Fusce", 546 | "velit", "justo", "laoreet", "sed", "massa", "et", "tincidunt", "elementum", "risus", "In", "placerat", 547 | "auctor", "pellentesque", "Aliquam", "at", "tortor", "metus", "Donec", "sollicitudin", "in", "nunc", "eget", 548 | "pretium", "In", "non", "dictum", "erat", "Mauris", "eget", "sem", "elit", "Duis", "malesuada", "nulla", "eu", 549 | "ultrices", "gravida", "Etiam", "nec", "mattis", "leo", "Maecenas", "ornare", "diam", "sed", "nisl", "cursus", 550 | "aliquam", "Aliquam", "erat", "volutpat", "Nullam", "commodo", "nulla", "ut", "enim", "iaculis", "convallis", 551 | "Aenean", "id", "sagittis", "lorem", "Donec", "varius", "accumsan", "augue", "eget", "cursus", "Ut", "dui", 552 | "nibh", "sodales", "quis", "porttitor", "at", "tristique", "ut", "tellus", "Donec", "vitae", "dapibus", "neque", 553 | "Maecenas", "nec", "ultricies", "ante", "quis", "congue", "tellus", "Vivamus", "cursus", "nisl", "ac", "nibh", 554 | "tempus", "eu", "iaculis", "nibh", "molestie", "Etiam", "tempus", "dolor", "nec", "consectetur", "tempor", 555 | "orci", "purus", "malesuada", "augue", "ut", "pharetra", "leo", "metus", "sed", "urna", "In", "suscipit", 556 | "placerat", "velit", "nec", "eleifend", "Maecenas", "quis", "condimentum", "mi", "nec", "blandit", "justo"}); 557 | 558 | test_ascending_descending(std::vector{ 559 | "Lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", "Praesent", "a", "posuere", 560 | "lorem", "Nam", "porttitor", "viverra", "nisl", "ac", "adipiscing", "tortor", "ornare", "vel", "Fusce", 561 | "velit", "justo", "laoreet", "sed", "massa", "et", "tincidunt", "elementum", "risus", "In", "placerat", 562 | "auctor", "pellentesque", "Aliquam", "at", "tortor", "metus", "Donec", "sollicitudin", "in", "nunc", "eget", 563 | "pretium", "In", "non", "dictum", "erat", "Mauris", "eget", "sem", "elit", "Duis", "malesuada", "nulla", "eu", 564 | "ultrices", "gravida", "Etiam", "nec", "mattis", "leo", "Maecenas", "ornare", "diam", "sed", "nisl", "cursus", 565 | "aliquam", "Aliquam", "erat", "volutpat", "Nullam", "commodo", "nulla", "ut", "enim", "iaculis", "convallis", 566 | "Aenean", "id", "sagittis", "lorem", "Donec", "varius", "accumsan", "augue", "eget", "cursus", "Ut", "dui", 567 | "nibh", "sodales", "quis", "porttitor", "at", "tristique", "ut", "tellus", "Donec", "vitae", "dapibus", "neque", 568 | "Maecenas", "nec", "ultricies", "ante", "quis", "congue", "tellus", "Vivamus", "cursus", "nisl", "ac", "nibh", 569 | "tempus", "eu", "iaculis", "nibh", "molestie", "Etiam", "tempus", "dolor", "nec", "consectetur", "tempor", 570 | "orci", "purus", "malesuada", "augue", "ut", "pharetra", "leo", "metus", "sed", "urna", "In", "suscipit", 571 | "placerat", "velit", "nec", "eleifend", "Maecenas", "quis", "condimentum", "mi", "nec", "blandit", "justo"}); 572 | 573 | run_exhaustive_tests(); 574 | } 575 | 576 | // Permission is hereby granted, free of charge, to any person obtaining a copy 577 | // of this software and associated documentation files (the "Software"), to deal 578 | // in the Software without restriction, including without limitation the rights 579 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 580 | // copies of the Software, and to permit persons to whom the Software is 581 | // furnished to do so, subject to the following conditions: 582 | // 583 | // The above copyright notice and this permission notice shall be included in 584 | // all copies or substantial portions of the Software. 585 | // 586 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 587 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 588 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 589 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 590 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 591 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 592 | // THE SOFTWARE. 593 | -------------------------------------------------------------------------------- /sorting.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.20827.3 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sorting", "sorting.VS2013.vcxproj", "{45FC4B3A-675B-4B93-8CB0-94CCE965A6D7}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {45FC4B3A-675B-4B93-8CB0-94CCE965A6D7}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {45FC4B3A-675B-4B93-8CB0-94CCE965A6D7}.Debug|Win32.Build.0 = Debug|Win32 16 | {45FC4B3A-675B-4B93-8CB0-94CCE965A6D7}.Release|Win32.ActiveCfg = Release|Win32 17 | {45FC4B3A-675B-4B93-8CB0-94CCE965A6D7}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | --------------------------------------------------------------------------------