-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQuickSort.java
More file actions
163 lines (141 loc) · 5.67 KB
/
Copy pathQuickSort.java
File metadata and controls
163 lines (141 loc) · 5.67 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
import java.util.Random;
/**
* QuickSort
* @author Daniel Pantyukhov && Valentim Khakhitva
* @version 1.0 [public]
*/
public class QuickSort extends Sort {
private static int cutoff = 16;
private static final Random rand = new Random();
/**
* Sorts the array using the quicksort algorithm
* @param <T> generic type for the sorted array
* @param a array to be sorted
*/
public static <T extends Comparable<T>> void sort(T[] a){
sort(a, 0, a.length - 1);
}
/**
* Sorts one part of the array specified by the low and high indexes
* @param <T> generic type for the sorted array
* @param a array to be sorted
* @param low index of the first element of the subarray
* @param high index of the last element of the subarray
*/
private static <T extends Comparable<T>> void sort(T[] a, int low, int high){
if (high <= low + cutoff){
insertionSort(a, low, high);
return;
}
int j = partition(a, low, high);
sort(a, low, j - 1);
sort(a, j + 1, high);
}
/**
* Partitions the array into two parts
* @param <T> generic type for the sorted array
* @param a array to be partitioned
* @param low index of the first element of the subarray
* @param high index of the last element of the subarray
* @return index of the partitioning element
*/
private static <T extends Comparable<T>> int partition(T[] a, int low, int high){
int randomIndex = low + rand.nextInt(high - low + 1);
exchange(a, low, randomIndex); // Move the random element to the first position to use as a comparison element
int i = low, j = high + 1;
T v = a[low]; // Pivô for comparison
while (true){
while (less(a[++i], v)) if (i == high) break; // i -> Search for elements greater than the pivot
while (less(v, a[--j])) if (j == low) break; // j -> Search for elements less than the pivot
if (i >= j) break; // If the pointers cross, the partition is complete
exchange(a, i, j); // Exchange the elements that are in the wrong partition
}
exchange(a, low, j); // Swap the pivot with the element at the partition index (Its apropiate position)
return j;
}
/**
* Sorts the array using the quicksort algorithm with median of three partitioning and insertion sort for small subarrays (cutoff)
* @param <T> generic type for the sorted array
* @param a array to be sorted
*/
public static <T extends Comparable<T>> void medianSort(T[] a){
medianSort(a, 0, a.length - 1);
}
/**
* Sorts one part of the array specified by the low and high indexes using median of three partitioning
* @param <T> generic type for the sorted array
* @param a array to be sorted
* @param low index of the first element of the subarray
* @param high index of the last element of the subarray
*/
private static <T extends Comparable<T>> void medianSort(T[] a, int low, int high){
if (high <= low + cutoff){
insertionSort(a, low, high);
return;
}
int j = medianPartition(a, low, high);
medianSort(a, low, j - 1);
medianSort(a, j + 1, high);
}
/**
* Partitions the array into two parts using median of three partitioning
* @param <T> generic type for the sorted array
* @param a array to be partitioned
* @param low index of the first element of the subarray
* @param high index of the last element of the subarray
* @return index of the partitioning element
*/
public static <T extends Comparable<T>> int medianPartition(T [] a, int low, int high){
int mid = (low + high) / 2;
if (less(a[mid], a[low])) exchange(a, low, mid);
if (less(a[high], a[low])) exchange(a, low, high);
if (less(a[high], a[mid])) exchange(a, mid, high);
exchange(a, low + 1, mid);
T v = a[low + 1];
int i = low + 1, j = high;
while (true){
while (less(a[++i], v));
while (less(v, a[--j]));
if (i >= j) break;
exchange(a, i, j);
}
exchange(a, low + 1, j);
return j;
}
/**
* Sorts the array using insertion sort algorithm (used for small subarrays)
* @param <T> generic type for the sorted array
* @param a array to be sorted
* @param low index of the first element of the subarray
* @param high index of the last element of the subarray
*/
public static <T extends Comparable<T>> void insertionSort(T[] a, int low, int high){
for (int i = low + 1; i <= high; i++){
T temp = a[i];
int j;
for(j = i - 1; j >= low && less(temp,a[j]); j--){
a[j + 1] = a[j];
}
a[j + 1] = temp;
}
}
/**
* Returns the k-th smallest element of the array
* @param <T> generic type for the sorted array
* @param a array to be sorted
* @param n index of the k-th smallest element
* @return the k-th smallest element of the array
*/
public static <T extends Comparable<T>> T quickSelect(T[] a, int n){
int low = 0, high = a.length - 1;
while (high > low){
int j = partition(a, low, high);
if (j < n) low = j + 1;
else if (j > n) high = j - 1;
else return a[j];
}
return a[low];
}
public static void main(String[] args) {
}
}