TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
count_inversions.cpp
Go to the documentation of this file.
1
43#include <cassert>
44#include <cstdint>
45#include <iostream>
46#include <vector>
47
52namespace sorting {
57namespace inversion {
58
59// Functions used --->
60// int mergeSort(int* arr, int* temp, int left, int right);
61// int merge(int* arr, int* temp, int left, int mid, int right);
62// int countInversion(int* arr, const int size);
63// void show(int* arr, const int size);
64
84template <typename T>
85uint32_t merge(T* arr, T* temp, uint32_t left, uint32_t mid, uint32_t right) {
86 uint32_t i = left; /* i --> index of left sub-array */
87 uint32_t j = mid + 1; /* j --> index for right sub-array */
88 uint32_t k = left; /* k --> index for resultant array temp */
89 uint32_t inv_count = 0; // inversion count
90
91 while ((i <= mid) && (j <= right)) {
92 if (arr[i] <= arr[j]) {
93 temp[k++] = arr[i++];
94 } else {
95 temp[k++] = arr[j++];
96 inv_count +=
97 (mid - i +
98 1); // tricky; may vary depending on selection of sub-array
99 }
100 }
101 // Add remaining elements from the larger subarray to the end of temp
102 while (i <= mid) {
103 temp[k++] = arr[i++];
104 }
105 while (j <= right) {
106 temp[k++] = arr[j++];
107 }
108 // Copy temp[] to arr[]
109 for (k = left; k <= right; k++) {
110 arr[k] = temp[k];
111 }
112 return inv_count;
113}
114
131template <typename T>
132uint32_t mergeSort(T* arr, T* temp, uint32_t left, uint32_t right) {
133 uint32_t mid = 0, inv_count = 0;
134 if (right > left) {
135 // midpoint to split the array
136 mid = (right + left) / 2;
137 // Add inversions in left and right sub-arrays
138 inv_count += mergeSort(arr, temp, left, mid); // left sub-array
139 inv_count += mergeSort(arr, temp, mid + 1, right);
140
141 // inversions in the merge step
142 inv_count += merge(arr, temp, left, mid, right);
143 }
144 return inv_count;
145}
146
163template <class T>
164uint32_t countInversion(T* arr, const uint32_t size) {
165 std::vector<T> temp;
166 temp.reserve(size);
167 temp.assign(size, 0);
168 return mergeSort(arr, temp.data(), 0, size - 1);
169}
170
178template <typename T>
179void show(T* arr, const uint32_t array_size) {
180 std::cout << "Printing array: \n";
181 for (uint32_t i = 0; i < array_size; i++) {
182 std::cout << " " << arr[i];
183 }
184 std::cout << "\n";
185}
186
187} // namespace inversion
188} // namespace sorting
189
194static void test() {
195 // Test 1
196 std::vector<uint64_t> arr1 = {
197 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84,
198 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67,
199 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50,
200 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
201 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
202 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
203 uint32_t size1 = arr1.size();
204 uint32_t inv_count1 = 4950;
205 uint32_t result1 = sorting::inversion::countInversion(arr1.data(), size1);
206 assert(inv_count1 == result1);
207 // Test 2
208 std::vector<int> arr2 = {22, 66, 75, 23, 11, 87, 2, 44, 98, 43};
209 uint32_t size2 = arr2.size();
210 uint32_t inv_count2 = 20;
211 uint32_t result2 = sorting::inversion::countInversion(arr2.data(), size2);
212 assert(inv_count2 == result2);
213 // Test 3
214 std::vector<double> arr3 = {33.1, 45.2, 65.4, 76.5, 1.0,
215 2.9, 5.4, 7.7, 88.9, 12.4};
216 uint32_t size3 = arr3.size();
217 uint32_t inv_count3 = 21;
218 uint32_t result3 = sorting::inversion::countInversion(arr3.data(), size3);
219 assert(inv_count3 == result3);
220 // Test 4
221 std::vector<char> arr4 = {'a', 'b', 'c', 'd', 'e'};
222 uint32_t size4 = arr4.size();
223 uint32_t inv_count4 = 0;
224 uint32_t result4 = sorting::inversion::countInversion(arr4.data(), size4);
225 assert(inv_count4 == result4);
226}
227
228// /**
229// * @brief Program Body contains all main funtionality
230// * @returns void
231// */
232// template <typename T>
233// static void body() {
234// // Input your own sequence
235// uint_t size;
236// T input;
237// std::cout << "Enter number of elements:";
238// std::cin >> size;
239//
240// std::vector<T> arr;
241// arr.reserve(size);
242//
243// std::cout << "Enter elements -->\n";
244// for (uint64_t i=1; i<=size; i++) {
245// std::cout << "Element "<< i <<" :";
246// std::cin >> input;
247// arr.push_back(input);
248// }
249//
250// if (size != arr.size()) {
251// size = arr.size();
252// }
253//
254// std::cout << "\n";
255// sorting::inversion::show(arr.data(), size);
256// std::cout << "\n";
257//
258// // Counting inversions
259// std::cout << "\nThe number of inversions: "<<
260// sorting::inversion::countInversion(arr.data(), size) << "\n";
261//
262// // Output sorted array
263// std::cout << "\nSorted array --> \n";
264// sorting::inversion::show(arr.data(), size);
265// }
266
271int main() {
272 test(); // Run test implementations
273 // body(); // test your own array
274 return 0;
275}
uint32_t countInversion(T *arr, const uint32_t size)
Function countInversion() returns the number of inversion present in the input array....
static void test()
Test implementations.
uint32_t merge(T *arr, T *temp, uint32_t left, uint32_t mid, uint32_t right)
Function to merge two sub-arrays.
int main()
Program Body contains all main funtionality.
uint32_t mergeSort(T *arr, T *temp, uint32_t left, uint32_t right)
Implement merge Sort and count inverions while merging.
Functions for counting inversions using Merge Sort algorithm.
for working with vectors