-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsortingbasic.cpp
More file actions
202 lines (188 loc) · 5.54 KB
/
sortingbasic.cpp
File metadata and controls
202 lines (188 loc) · 5.54 KB
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include <bits/stdc++.h>
using namespace std;
int* bubblesort(int arr[], int n){ //theta(n2)
for(int i = 0; i < n - 1; i++){
for(int j = 0; j < n - i - 1; j++){ //because the last i elements are already sorted
if(arr[j] > arr[j + 1]){
swap(arr[j], arr[j + 1]);
}
}
}
return arr;
}
int* bubblesortoptimised(int arr[], int n){ //linear time in some cases, or O(n2)
bool swapped;
for(int i = 0; i < n - 1; i++){
swapped = false;
for(int j = 0; j < n - i - 1; j++){
if(arr[j] > arr[j + 1]){
swap(arr[j], arr[j + 1]);
swapped = true;
}
}
if(swapped == false){
return arr;
}
}
return arr;
}
int* selectionsort(int arr[], int n){ //theta(n2)
for (int i = 0; i < n - 1; i++)
{
for(int j = i + 1; j < n; j++){
if(arr[j] < arr[i]){
swap(arr[i], arr[j]);
}
}
}
return arr;
}
int* insertionsort(int arr[], int n){ //best case: linear time(already sorted array)
for(int i = 1; i < n; i++){ //worst case: theta(n2) (reverse sorted array)
int key = arr[i]; //use insertion sort for small sized arrays
int j = i - 1;
while(j >= 0 && arr[j] > key){
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
return arr;
}
void mergetwoSortedArrays(int a[], int b[], int m, int n){ //O(m + n) time complexity , aux space:O(m+n)//if we store it in another array
int i = 0, j = 0;
while(i < m && j < n){ //will work when both arrays has elements, but won't work when
if(a[i] > b[j]){ //one array has no elements, so we have to print the rest of the
cout << b[j] << " "; //elements (leftover)
j++;
}else{
cout << a[i] << " ";
i++;
}
}
while(i < m){
cout << a[i] << " ";
i++;
}
while(j < n){
cout << b[j] << " ";
j++;
}
}
int* merge(int arr[], int l, int m, int h){ //time complexity: O(n), aux space: O(n)
int size_left = m - l + 1, size_right = h - m;
int left[size_left], right[size_right];
for(int i = 0; i < size_left; i++){
left[i] = arr[i];
}
for(int j = 0; j < size_right; j++){
right[j] = arr[m + j + 1];
}
int i = 0, j =0, k = l;
while(i < size_left && j < size_right){
if(left[i] <= right[j]){ //<= sign very imp for stability in merge sort, because if the ele is first in left arr it should be first in final arr also
arr[k++] = left[i++]; //arr[k++] can also be written as arr[k] and in next line k++
}else{
arr[k++] = right[j++];
}
}
while(i < size_left){
arr[k++] = left[i++];
}
while(j < size_right){
arr[k++] = right[j++];
}
return arr;
}
int* mergeSort(int arr[], int l, int r){ //To check that there are atleast two elements in arr
int *p;
if(r > l){
int m = l + (r - l)/2; //same as (r+l)/2, but to prevent overflow, we used this
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
p = merge(arr, l, m, r);
}
return p;
}
int partition_naive(int arr[], int l, int h, int p){ // time complexity: O(n) with three traversals
int temp[h - l + 1], idx = 0; // aux space: O(n)
for(int i = l; i <= h; i++){
if(arr[i] <= arr[p]){
temp[idx] = arr[i];
idx++;
}
}
for(int i = l; i <= h; i++){
if(arr[i] > arr[p]){
temp[idx] = arr[i];
idx++;
}
}
for(int i = l; i <= h; i++){
arr[i] = temp[i - l];
}
return idx;
}
int lomieto_partition(int arr[], int l, int h){ //one traversal, O(1) extra space
int i = l - 1, pivot = arr[h];
for(int j = l; j <= h - 1; j++){
if(arr[i] < pivot){
i++;
swap(arr[i], arr[j]);
}
}
swap(arr[i + 1], arr[h]);
return i + 1;
}
int hoare_partition(int arr[], int l, int h){ //O(1) space, one traversal, works better than lomieto partition
int i = l - 1, j = h + 1;
int pivot = arr[l];
while(true){
do{
i++;
}while(arr[i] < pivot);
do{
j--;
}while(arr[j] > pivot);
if(i >= j){
return j;
}
swap(arr[i], arr[j]);
}
return j;
}
int* quickSort_lomieto(int arr[], int l, int h){
if(l < h){
int p = lomieto_partition(arr, l, h);
quickSort_lomieto(arr, l, p - 1);
quickSort_lomieto(arr, l, p + 1);
}
return arr;
}
int* quicksort_hoare(int arr[], int l, int h){
if(l < h){
int p = hoare_partition(arr, l, h);
quicksort_hoare(arr, l, p); //here it is p and not p-1 because hoare's partition does not fix any element at its correct position
quicksort_hoare(arr, p + 1, h);
}
return arr;
}
int main(){
int arr[] = {2, 10, 8, 7};
// int *p = bubblesort(arr, 4);
// int *p = bubblesortoptimised(arr, 4);
// int *p = selectionsort(arr, 4);
// int *p = insertionsort(arr, 4);
// int a[] = {10, 15, 20, 40};
// int b[] = {5, 6, 6, 10, 15};
// mergetwoSortedArrays(a, b, 4, 5);
// int *p = mergeSort(arr, 0, 3);
// int p = hoare_partition(arr, 0, 3);
// int *p = partition_naive(arr, 0, 3, 3);
int *p = quicksort_hoare(arr, 0, 3);
for(int i = 0; i < 4; i++){
cout << p[i] << " ";
}
cout << endl;
return 0;
}