-
Notifications
You must be signed in to change notification settings - Fork 0
/
timSort.h
141 lines (116 loc) · 3.58 KB
/
timSort.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#pragma once
#include <vector>
#include <algorithm>
#include "Food.h"
// Insertion sort in ascending order
void insertionSort(vector<Food>& arr, int fieldNumber, int l, int r) {
for (int i = 1; i < arr.size(); i++) {
int j = i - 1;
double prevValue = arr[j].getMacro(fieldNumber);
double currValue = arr[i].getMacro(fieldNumber);
//checks stay in bounds and if the current value is less than the previous value
while (j >= 0 && currValue < prevValue) {
// swap
swap(arr[j + 1], arr[j]);
// Food temp = arr[j + 1];
// arr[j + 1] = arr[j];
// arr[j] = temp;
j--;
// update currValue if j is still in bounds
if (j >= 0) {
prevValue = arr[j].getMacro(fieldNumber);
}
}
}
}
// Merge function merges the sorted runs
void merge(vector<Food>& arr, int fieldNumber, int l, int m, int r) {
// Original array is broken in two parts
// left and right array
int len1 = m - l + 1;
int len2 = r - m;
vector<Food> left;
vector<Food> right;
// Copy data to temp vectors left and right
for (int i = 0; i < len1; i++) {
left.push_back(arr[l + i]);
}
for (int i = 0; i < len2; i++) {
right.push_back(arr[m + 1 + i]);
}
int i = 0;
int j = 0;
int k = l;
// After comparing, we
// merge those two array
// in larger sub array
while (i < len1 && j < len2) {
double leftValue = left[i].getMacro(fieldNumber);
double rightValue = right[j].getMacro(fieldNumber);
// If leftValue <= rightValue, then put left[i] in arr[k] and increment i
if (leftValue <= rightValue) {
arr[k] = left[i];
i++;
// Else put right[j] in arr[k] and increment j
} else {
arr[k] = right[j];
j++;
}
// Increment k
k++;
}
// Copy remaining elements of left, if any
while (i < len1) {
arr[k] = left[i];
k++;
i++;
}
// Copy remaining element of right, if any
while (j < len2) {
arr[k] = right[j];
k++;
j++;
}
}
// Iterative Timsort function to sort the
// array[0...n-1] (similar to merge sort)
vector<Food> timSort(const vector<Food>& data, int fieldNumber, bool ascending) {
//copy data into arr
vector<Food> arr(data);
int RUN = 16;
int n = arr.size();
// Sort individual subarrays of size RUN
for (int i = 0; i < n; i += RUN) {
int right = min((i + RUN - 1), (n - 1));
insertionSort(arr, fieldNumber, i, right);
}
// Start merging from size
// RUN (or 16). It will
// merge to form size 16,
// then 32, 64, 128, 256
// and so on ....
for (int j = RUN; j < n; j *= 2) {
// pick starting point of
// left sub array. We
// are going to merge
// arr[left..left+size-1]
for (int left = 0; left < n; left += 2*j) {
// find ending point of
// left sub array
// mid+1 is starting point
// of right sub array
int mid = left + j - 1;
int right = min((left + 2*j - 1), (n-1));
// merge sub array arr[left.....mid] &
// arr[mid+1....right]
if (mid < right) {
merge(arr, fieldNumber, left, mid, right);
}
}
}
// Reverse arr if ascending
if (ascending) {
reverse(arr.begin(), arr.end());
}
return arr;
}