sort.h
Go to the documentation of this file.
1 /*
2  * This file is part of the alglib project.
3  *
4  * (c) Divyanshu Kakwani <divkakwani@gmail.com>
5  *
6  * For the full copyright and license information, please view the LICENSE file
7  * that was distributed with this source code.
8  *
9  * This library contains a collection of sorting algorithms, all of which can be
10  * applied on STL containers.The functions are templatized by the iterator type.
11  * A sorting function in general has the following interface:
12  * <sorting_algorithm>(BEGIN_ITERATOR, END_ITERATOR, GREATER functor);
13  *
14  * Sorting Algorithms :
15  * Comparsion Sorting Algorithms
16  * Bubble Sort, Insertion sort, Selection sort, Merge sort, Quicksort,
17  * Shell sort, Heap sort
18 
19  */
20 
21 // Document this file
24 #pragma once
25 
26 #include <vector>
27 #include <algorithm>
28 #include <iterator>
29 #include <functional>
31 
32 
33 namespace alglib {
34 namespace sort {
35 
36 
37 /* Sorts the elements in [first, last) using selection sort
38  * @first The starting iterator of the range
39  * @last The one-past-the-end iterator of the range.
40  */
41 template<typename ForwardIter, typename BinaryPred>
42 void selection_sort(ForwardIter first, ForwardIter last, const BinaryPred& LT) {
43  for (auto it = first; it != last; it++)
44  std::swap(*it, *std::min_element(it, last, LT));
45 
46  /* Analysis
47  * Proof of Correctness:
48  * We prove it using the following invariant:
49  * Prior to an iteration of the loop, A[first..it-1] contains
50  * the smallest (it-first) elements of A in a non-decreasing order.
51  * Initialization: Initially, it = first, so A[first..first-1] contains
52  * no element. Hence it is trivially sorted.
53  * Maintenance: A[first..it-1] is sorted prior to an iteration, and in
54  * the loop A[it] is set to a minimum element in A[it..last].
55  * A[it] >= E, E ϵ A[first..it-1] because prior to the iteration,
56  * A[it..last] did not contain any element greater than E,
57  * E ϵ A[first..it-1]. Hence, A[first..it] contains its elements in a
58  * non-decreasing order. Further, the range also contains the smallest
59  * (it-first+1) elemnts of A since one more is added in the loop.
60  * Termination: At the end, we have, A[first..last] contains all the
61  * the elemets in a non-decreasing order. This proves the claim.
62  *
63  * Stable: Yes (Depends on the implementation of min_element. If it
64  * returns the first minimum element, then it is stable.)
65  * In-place: Yes
66  * Time-Complexity Gurantee: O(n^2).
67  * The loop runs n times and each of the iteration invoke min_element,
68  * which takes O(i) time where i goes from 1 to n.
69  * Mutual-Exclusion: required.
70  */
71 }
72 
73 
74 template<typename ForwardIter>
75 inline void selection_sort(ForwardIter first, ForwardIter last) {
76  selection_sort(first, last, std::less<typename ForwardIter::value_type>());
77 }
78 
79 
80 // Quick sort helper function
81 template<typename RandomAccessIter, typename BinaryPred>
82 RandomAccessIter randomized_partition(RandomAccessIter first,
83  RandomAccessIter last,
84  const BinaryPred& LT) {
85  /* The function selects a random element in [first, last) as pivot and
86  * partitions the interval around it.
87  * The part
88  */
89  int sz = std::distance(first, last);
90 
91  RandomAccessIter it = first + rand() % sz; // O(n) cost
92  std::swap(*it, *(last - 1));
93  auto pivot = last - 1;
94 
95  RandomAccessIter sep = first; // sep heads the larger-elements partition
96  for (auto it = first; it != last; it++) {
97  if (*it < *pivot) {
98  std::swap(*it, *sep);
99  sep++;
100  }
101  }
102  std::swap(*pivot, *sep);
103  return sep;
104 }
105 
106 template<typename RandomAccessIter, typename BinaryPred>
107 void quick_sort(RandomAccessIter first, RandomAccessIter last,
108  const BinaryPred& LT) {
109  if (first < last) {
110  RandomAccessIter pivot = randomized_partition(first, last, LT);
111  quick_sort(first, pivot, LT);
112  quick_sort(pivot + 1, last, LT);
113  }
114 }
115 
116 
117 template<typename RandomAccessIter>
118 void quick_sort(RandomAccessIter first, RandomAccessIter last) {
119  quick_sort(first, last, std::less<typename RandomAccessIter::value_type>());
120 }
121 
122 
123 template<typename RandomAccessIter, typename BinaryPred>
124 void merge_sort(RandomAccessIter first, RandomAccessIter last,
125  const BinaryPred& LT) {
126  int sz = std::distance(first, last);
127  if (sz > 1) {
128  std::vector<typename RandomAccessIter::value_type>
129  subarr1(first, first + sz / 2);
130  std::vector<typename RandomAccessIter::value_type>
131  subarr2(first + sz / 2, last);
132  merge_sort(subarr1.begin(), subarr1.end(), LT);
133  merge_sort(subarr2.begin(), subarr2.end(), LT);
134  std::merge(subarr1.begin(), subarr1.end(),
135  subarr2.begin(), subarr2.end(), first);
136  }
137 }
138 
139 template<typename RandomAccessIter>
140 void merge_sort(RandomAccessIter first, RandomAccessIter last) {
141  merge_sort(first, last, std::less<typename RandomAccessIter::value_type>());
142 }
143 
144 
145 template<typename RandomAccessIter, typename BinaryPred>
146 void heap_sort(RandomAccessIter first, RandomAccessIter last,
147  const BinaryPred& LT) {
148  typedef
149  typename std::iterator_traits<RandomAccessIter>::value_type val_type;
150 
152 
153  for (RandomAccessIter it = first; it != last; it++)
154  H.insert(*it);
155 
156  for (RandomAccessIter it = first; it != last; it++) {
157  *it = H.get_min();
158  H.delete_min();
159  }
160 }
161 
162 
163 template<typename RandomAccessIter>
164 void heap_sort(RandomAccessIter first, RandomAccessIter last) {
165  heap_sort(first, last, std::less<typename RandomAccessIter::value_type>());
166 }
167 
168 
169 } // end of sort namespace
170 } // end of alglib namespace
171 
void delete_min()
Definition: binary_heap.h:224
void quick_sort(RandomAccessIter first, RandomAccessIter last, const BinaryPred &LT)
Definition: sort.h:107
Definition: bimap.h:17
void insert(const elt_t &elt)
Definition: binary_heap.h:218
Definition: binary_heap.h:213
void selection_sort(ForwardIter first, ForwardIter last, const BinaryPred &LT)
Definition: sort.h:42
const elt_t & get_min() const
Definition: binary_heap.h:221
RandomAccessIter randomized_partition(RandomAccessIter first, RandomAccessIter last, const BinaryPred &LT)
Definition: sort.h:82
void heap_sort(RandomAccessIter first, RandomAccessIter last, const BinaryPred &LT)
Definition: sort.h:146
void merge_sort(RandomAccessIter first, RandomAccessIter last, const BinaryPred &LT)
Definition: sort.h:124