157 lines
4.6 KiB
Java
157 lines
4.6 KiB
Java
package util;
|
|
|
|
public class Sorter {
|
|
public void sort(int[] array) {
|
|
if (array == null || array.length <= 1) return;
|
|
|
|
int n = array.length;
|
|
int[] temp = new int[n];
|
|
|
|
while (true) {
|
|
int i = 0;
|
|
int merges = 0;
|
|
|
|
while (i < n) {
|
|
// Find first run
|
|
int left = i;
|
|
while (i + 1 < n && array[i] <= array[i + 1]) i++;
|
|
int mid = i;
|
|
i++;
|
|
|
|
if (i >= n) break;
|
|
|
|
// Find second run
|
|
while (i + 1 < n && array[i] <= array[i + 1]) i++;
|
|
int right = i;
|
|
i++;
|
|
|
|
// Merge both runs
|
|
merge(array, temp, left, mid, right);
|
|
merges++;
|
|
}
|
|
|
|
if (merges == 0) break;
|
|
}
|
|
}
|
|
|
|
private void merge(int[] array, int[] temp, int left, int mid, int right) {
|
|
System.arraycopy(array, left, temp, left, right - left + 1);
|
|
|
|
int i = left;
|
|
int j = mid + 1;
|
|
int k = left;
|
|
|
|
while (i <= mid && j <= right) {
|
|
if (temp[i] <= temp[j]) {
|
|
array[k++] = temp[i++];
|
|
} else {
|
|
array[k++] = temp[j++];
|
|
}
|
|
}
|
|
while (i <= mid) array[k++] = temp[i++];
|
|
while (j <= right) array[k++] = temp[j++];
|
|
}
|
|
|
|
public void mergeSort(int[] array) {
|
|
if (array == null || array.length <= 1) return;
|
|
int[] temp = new int[array.length];
|
|
mergeSortRecursive(array, temp, 0, array.length - 1);
|
|
}
|
|
|
|
private void mergeSortRecursive(int[] array, int[] temp, int left, int right) {
|
|
if (left >= right) return;
|
|
int mid = (left + right) >>> 1;
|
|
mergeSortRecursive(array, temp, left, mid);
|
|
mergeSortRecursive(array, temp, mid + 1, right);
|
|
mergeDescending(array, temp, left, mid, right);
|
|
}
|
|
|
|
private void mergeDescending(int[] array, int[] temp, int left, int mid, int right) {
|
|
System.arraycopy(array, left, temp, left, right - left + 1);
|
|
|
|
int i = left;
|
|
int j = mid + 1;
|
|
int k = left;
|
|
|
|
while (i <= mid && j <= right) {
|
|
if (temp[i] >= temp[j]) {
|
|
array[k++] = temp[i++];
|
|
} else {
|
|
array[k++] = temp[j++];
|
|
}
|
|
}
|
|
while (i <= mid) array[k++] = temp[i++];
|
|
while (j <= right) array[k++] = temp[j++];
|
|
}
|
|
|
|
public void insertionSort(int[] array) {
|
|
if (array == null || array.length <= 1) return;
|
|
for (int i = 1; i < array.length; i++) {
|
|
int key = array[i];
|
|
int j = i - 1;
|
|
while (j >= 0 && array[j] < key) {
|
|
array[j + 1] = array[j];
|
|
j--;
|
|
}
|
|
array[j + 1] = key;
|
|
}
|
|
}
|
|
|
|
public void optimizedMergeSort(int[] array) {
|
|
if (array == null || array.length <= 1) return;
|
|
int[] temp = new int[array.length];
|
|
optimizedMergeSortRecursive(array, temp, 0, array.length - 1);
|
|
}
|
|
|
|
private void optimizedMergeSortRecursive(int[] array, int[] temp, int left, int right) {
|
|
if (left >= right) return;
|
|
if (right - left + 1 <= 10) {
|
|
insertionSortRange(array, left, right);
|
|
return;
|
|
}
|
|
int mid = (left + right) >>> 1;
|
|
optimizedMergeSortRecursive(array, temp, left, mid);
|
|
optimizedMergeSortRecursive(array, temp, mid + 1, right);
|
|
mergeDescending(array, temp, left, mid, right);
|
|
}
|
|
|
|
private void insertionSortRange(int[] array, int left, int right) {
|
|
for (int i = left + 1; i <= right; i++) {
|
|
int key = array[i];
|
|
int j = i - 1;
|
|
while (j >= left && array[j] < key) {
|
|
array[j + 1] = array[j];
|
|
j--;
|
|
}
|
|
array[j + 1] = key;
|
|
}
|
|
}
|
|
|
|
public void testMergeSort() {
|
|
int[] array = new int[100];
|
|
Util util = new Util();
|
|
util.fillArrayRandom(array, 100);
|
|
Sorter mySorter = new Sorter();
|
|
mySorter.mergeSort(array);
|
|
util.printArray(array);
|
|
}
|
|
|
|
public void testOptimizedMergeSort() {
|
|
int[] array = new int[100];
|
|
Util util = new Util();
|
|
util.fillArrayRandom(array, 100);
|
|
Sorter mySorter = new Sorter();
|
|
mySorter.optimizedMergeSort(array);
|
|
util.printArray(array);
|
|
}
|
|
|
|
public static final void main(String[] args) {
|
|
int[] array = new int[100000000];
|
|
Util util = new Util();
|
|
util.fillArrayRandom(array, 10000000);
|
|
Sorter mySorter = new Sorter();
|
|
mySorter.sort(array);
|
|
|
|
}
|
|
}
|