Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
sorting Namespace Reference

Sorting algorithms. More...

Functions

template<class Iterator >
void merge (Iterator l, Iterator r, const Iterator e, char b[])
 merges 2 sorted adjacent segments into a larger sorted segment More...
 
template<class Iterator >
void non_recursive_merge_sort (const Iterator first, const Iterator last, const size_t n)
 bottom-up merge sort which sorts elements in a non-decreasing order More...
 
template<class Iterator >
void non_recursive_merge_sort (const Iterator first, const size_t n)
 bottom-up merge sort which sorts elements in a non-decreasing order More...
 
template<class Iterator >
void non_recursive_merge_sort (const Iterator first, const Iterator last)
 bottom-up merge sort which sorts elements in a non-decreasing order More...
 
int partition (int arr[], int low, int high)
 
void quickSort (int arr[], int low, int high)
 
template<typename T >
void shell_sort (T *arr, size_t LEN)
 
template<typename T , size_t N>
void shell_sort (T(&arr)[N])
 
template<typename T >
void shell_sort (std::vector< T > *arr)
 

Detailed Description

Sorting algorithms.

Function Documentation

◆ merge()

template<class Iterator >
void sorting::merge ( Iterator  l,
Iterator  r,
const Iterator  e,
char  b[] 
)

merges 2 sorted adjacent segments into a larger sorted segment

best-case = worst-case = O(n)

Parameters
lpoints to the left part
rpoints to the right part, end of left part
epoints to end of right part
bpoints at the buffer
57  {
58  // create 2 pointers to point at the buffer
59  auto p(reinterpret_cast<std::remove_reference_t<decltype(*l)>*>(b)), c(p);
60  // move the left part of the segment
61  for (Iterator t(l); r != t; ++t) *p++ = std::move(*t);
62  // while neither the buffer nor the right part has been exhausted
63  // move the smallest element of the two back to the container
64  while (e != r && c != p) *l++ = std::move(*r < *c ? *r++ : *c++);
65  // notice only one of the two following loops will be executed
66  // while the right part hasn't bee exhausted, move it back
67  while (e != r) *l++ = std::move(*r++);
68  // while the buffer hasn't bee exhausted, move it back
69  while (c != p) *l++ = std::move(*c++);
70 }
Here is the call graph for this function:

◆ non_recursive_merge_sort() [1/3]

template<class Iterator >
void sorting::non_recursive_merge_sort ( const Iterator  first,
const Iterator  last 
)

bottom-up merge sort which sorts elements in a non-decreasing order

Parameters
firstpoints to the first element
lastpoints to 1-step past the last element
86  {
87  non_recursive_merge_sort(first, last, last - first);
88 }
Here is the call graph for this function:

◆ non_recursive_merge_sort() [2/3]

template<class Iterator >
void sorting::non_recursive_merge_sort ( const Iterator  first,
const Iterator  last,
const size_t  n 
)

bottom-up merge sort which sorts elements in a non-decreasing order

sorts elements non-recursively by breaking them into small segments, merging adjacent segments into larger sorted segments, then increasing the sizes of segments by factors of 2 and repeating the same process. best-case = worst-case = O(n log(n))

Parameters
firstpoints to the first element
lastpoints to 1-step past the last element
nthe number of elements
26  {
27  // create a buffer large enough to store all elements
28  // dynamically allocated to comply with cpplint
29  char* buffer = new char[n * sizeof(*first)];
30  // buffer size can be optimized to largest power of 2 less than n
31  // elements divide the container into equally-sized segments whose
32  // length start at 1 and keeps increasing by factors of 2
33  for (size_t length(1); length < n; length <<= 1) {
34  // merge adjacent segments whose number is n / (length * 2)
35  Iterator left(first);
36  for (size_t counter(n / (length << 1)); counter; --counter) {
37  Iterator right(left + length), end(right + length);
38  merge(left, right, end, buffer);
39  left = end;
40  }
41  // if the number of remaining elements (n * 2 % length) is longer
42  // than a segment, merge the remaining elements
43  if ((n & ((length << 1) - 1)) > length)
44  merge(left, left + length, last, buffer);
45  }
46  delete[] buffer;
47 }
Here is the call graph for this function:

◆ non_recursive_merge_sort() [3/3]

template<class Iterator >
void sorting::non_recursive_merge_sort ( const Iterator  first,
const size_t  n 
)

bottom-up merge sort which sorts elements in a non-decreasing order

Parameters
firstpoints to the first element
nthe number of elements
77  {
78  non_recursive_merge_sort(first, first + n, n);
79 }
Here is the call graph for this function:

◆ partition()

int sorting::partition ( int  arr[],
int  low,
int  high 
)

This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot

37  {
38  int pivot = arr[high]; // taking the last element as pivot
39  int i = (low - 1); // Index of smaller element
40 
41  for (int j = low; j < high; j++) {
42  // If current element is smaller than or
43  // equal to pivot
44  if (arr[j] <= pivot) {
45  i++; // increment index of smaller element
46  int temp = arr[i];
47  arr[i] = arr[j];
48  arr[j] = temp;
49  }
50  }
51  int temp = arr[i + 1];
52  arr[i + 1] = arr[high];
53  arr[high] = temp;
54  return (i + 1);
55 }

◆ quickSort()

void sorting::quickSort ( int  arr[],
int  low,
int  high 
)

The main function that implements QuickSort arr[] --> Array to be sorted, low --> Starting index, high --> Ending index

63  {
64  if (low < high) {
65  int p = partition(arr, low, high);
66  quickSort(arr, low, p - 1);
67  quickSort(arr, p + 1, high);
68  }
69 }
Here is the call graph for this function:

◆ shell_sort() [1/3]

template<typename T >
void sorting::shell_sort ( std::vector< T > *  arr)

function overload - when input array is of type std::vector, simply send the data content and the data length to the above function.

75  {
76  shell_sort(arr->data(), arr->size());
77 }
Here is the call graph for this function:

◆ shell_sort() [2/3]

template<typename T >
void sorting::shell_sort ( T *  arr,
size_t  LEN 
)

Optimized algorithm - takes half the time by utilizing Mar

45  {
46  const unsigned int gaps[] = {701, 301, 132, 57, 23, 10, 4, 1};
47  const unsigned int gap_len = 8;
48  size_t i, j, g;
49 
50  for (g = 0; g < gap_len; g++) {
51  unsigned int gap = gaps[g];
52  for (i = gap; i < LEN; i++) {
53  T tmp = arr[i];
54 
55  for (j = i; j >= gap && (arr[j - gap] - tmp) > 0; j -= gap) {
56  arr[j] = arr[j - gap];
57  }
58 
59  arr[j] = tmp;
60  }
61  }
62 }

◆ shell_sort() [3/3]

template<typename T , size_t N>
void sorting::shell_sort ( T(&)  arr[N])

function overload - when input array is of a known length array type

67  {
68  shell_sort(arr, N);
69 }
Here is the call graph for this function:
std::move
T move(T... args)
sorting::partition
int partition(int arr[], int low, int high)
Definition: quick_sort.cpp:37
merge
void merge(int *arr, int l, int m, int r)
Definition: merge_sort.cpp:33
sorting::non_recursive_merge_sort
void non_recursive_merge_sort(const Iterator first, const Iterator last)
bottom-up merge sort which sorts elements in a non-decreasing order
Definition: non_recursive_merge_sort.cpp:86
std::left
T left(T... args)
std::end
T end(T... args)
sorting::quickSort
void quickSort(int arr[], int low, int high)
Definition: quick_sort.cpp:63
sorting::shell_sort
void shell_sort(std::vector< T > *arr)
Definition: shell_sort2.cpp:75