mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-08 02:04:31 +08:00
MergeSort: Simplify merge function (#3774)
* bug fix for CircularBuffer + refactoring + add unit tests * change Insertion sort to classical implementation + add isSorted function to SortUtils + add SortUtilsRandomGenerator for generating random values and arrays * little fix * simplify merge function in MergeSort * refactor one-liners Co-authored-by: Debasish Biswas <debasishbsws.abc@gmail.com>
This commit is contained in:
@ -1,5 +1,7 @@
|
|||||||
package com.thealgorithms.sorts;
|
package com.thealgorithms.sorts;
|
||||||
|
|
||||||
|
import static com.thealgorithms.sorts.SortUtils.less;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic merge sort algorithm.
|
* Generic merge sort algorithm.
|
||||||
*
|
*
|
||||||
@ -7,6 +9,9 @@ package com.thealgorithms.sorts;
|
|||||||
*/
|
*/
|
||||||
class MergeSort implements SortAlgorithm {
|
class MergeSort implements SortAlgorithm {
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private static Comparable[] aux;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic merge sort algorithm implements.
|
* Generic merge sort algorithm implements.
|
||||||
*
|
*
|
||||||
@ -16,6 +21,7 @@ class MergeSort implements SortAlgorithm {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T extends Comparable<T>> T[] sort(T[] unsorted) {
|
public <T extends Comparable<T>> T[] sort(T[] unsorted) {
|
||||||
|
aux = new Comparable[unsorted.length];
|
||||||
doSort(unsorted, 0, unsorted.length - 1);
|
doSort(unsorted, 0, unsorted.length - 1);
|
||||||
return unsorted;
|
return unsorted;
|
||||||
}
|
}
|
||||||
@ -25,11 +31,7 @@ class MergeSort implements SortAlgorithm {
|
|||||||
* @param left the first index of the array.
|
* @param left the first index of the array.
|
||||||
* @param right the last index of the array.
|
* @param right the last index of the array.
|
||||||
*/
|
*/
|
||||||
private static <T extends Comparable<T>> void doSort(
|
private static <T extends Comparable<T>> void doSort(T[] arr, int left, int right) {
|
||||||
T[] arr,
|
|
||||||
int left,
|
|
||||||
int right
|
|
||||||
) {
|
|
||||||
if (left < right) {
|
if (left < right) {
|
||||||
int mid = (left + right) >>> 1;
|
int mid = (left + right) >>> 1;
|
||||||
doSort(arr, left, mid);
|
doSort(arr, left, mid);
|
||||||
@ -47,54 +49,21 @@ class MergeSort implements SortAlgorithm {
|
|||||||
* @param right the last index of the array merges two parts of an array in
|
* @param right the last index of the array merges two parts of an array in
|
||||||
* increasing order.
|
* increasing order.
|
||||||
*/
|
*/
|
||||||
private static <T extends Comparable<T>> void merge(
|
@SuppressWarnings("unchecked")
|
||||||
T[] arr,
|
private static <T extends Comparable<T>> void merge(T[] arr, int left, int mid, int right) {
|
||||||
int left,
|
int i = left, j = mid + 1;
|
||||||
int mid,
|
System.arraycopy(arr, left, aux, left, right + 1 - left);
|
||||||
int right
|
|
||||||
) {
|
|
||||||
int length = right - left + 1;
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
T[] temp = (T[]) new Comparable[length];
|
|
||||||
int i = left;
|
|
||||||
int j = mid + 1;
|
|
||||||
int k = 0;
|
|
||||||
|
|
||||||
while (i <= mid && j <= right) {
|
for (int k = left; k <= right; k++) {
|
||||||
if (arr[i].compareTo(arr[j]) <= 0) {
|
if (j > right) {
|
||||||
temp[k++] = arr[i++];
|
arr[k] = (T) aux[i++];
|
||||||
|
} else if (i > mid) {
|
||||||
|
arr[k] = (T) aux[j++];
|
||||||
|
} else if (less(aux[j], aux[i])) {
|
||||||
|
arr[k] = (T) aux[j++];
|
||||||
} else {
|
} else {
|
||||||
temp[k++] = arr[j++];
|
arr[k] = (T) aux[i++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i <= mid) {
|
|
||||||
temp[k++] = arr[i++];
|
|
||||||
}
|
|
||||||
|
|
||||||
while (j <= right) {
|
|
||||||
temp[k++] = arr[j++];
|
|
||||||
}
|
|
||||||
|
|
||||||
System.arraycopy(temp, 0, arr, left, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Driver code
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
MergeSort mergeSort = new MergeSort();
|
|
||||||
|
|
||||||
Integer[] arr = { 4, 23, 6, 78, 1, 54, 231, 9, 12 };
|
|
||||||
mergeSort.sort(arr);
|
|
||||||
for (int i = 0; i < arr.length - 1; ++i) {
|
|
||||||
assert arr[i] <= arr[i + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] stringArray = { "c", "a", "e", "b", "d" };
|
|
||||||
mergeSort.sort(stringArray);
|
|
||||||
for (int i = 0; i < stringArray.length - 1; ++i) {
|
|
||||||
assert arr[i].compareTo(arr[i + 1]) <= 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,4 +35,13 @@ public class SortUtilsRandomGenerator {
|
|||||||
return random.nextDouble();
|
return random.nextDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to generate int value.
|
||||||
|
*
|
||||||
|
* @return int value [0, n)
|
||||||
|
*/
|
||||||
|
public static int generateInt(int n) {
|
||||||
|
return random.nextInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ class InsertionSortTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void testWithRandomArray(Function<Double[], Double[]> sortAlgorithm) {
|
private void testWithRandomArray(Function<Double[], Double[]> sortAlgorithm) {
|
||||||
int randomSize = (int) (SortUtilsRandomGenerator.generateDouble() * 10_000);
|
int randomSize = SortUtilsRandomGenerator.generateInt(10_000);
|
||||||
Double[] array = SortUtilsRandomGenerator.generateArray(randomSize);
|
Double[] array = SortUtilsRandomGenerator.generateArray(randomSize);
|
||||||
Double[] sorted = sortAlgorithm.apply(array);
|
Double[] sorted = sortAlgorithm.apply(array);
|
||||||
assertTrue(SortUtils.isSorted(sorted));
|
assertTrue(SortUtils.isSorted(sorted));
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
package com.thealgorithms.sorts;
|
package com.thealgorithms.sorts;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class MergeSortTest {
|
public class MergeSortTest {
|
||||||
|
|
||||||
private static MergeSort mergeSort= new MergeSort();
|
private MergeSort mergeSort;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
mergeSort = new MergeSort();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldAcceptWhenEmptyArrayIsPassed() {
|
void shouldAcceptWhenEmptyArrayIsPassed() {
|
||||||
@ -79,5 +85,11 @@ public class MergeSortTest {
|
|||||||
assertArrayEquals(expected, sorted);
|
assertArrayEquals(expected, sorted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldAcceptWhenRandomArrayIsPassed() {
|
||||||
|
int randomSize = SortUtilsRandomGenerator.generateInt(10_000);
|
||||||
|
Double[] array = SortUtilsRandomGenerator.generateArray(randomSize);
|
||||||
|
Double[] sorted = mergeSort.sort(array);
|
||||||
|
assertTrue(SortUtils.isSorted(sorted));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user