refactor: SelectionSort
like classes and their tests (#5265)
* Refactor: Adding test common approach, adding javadocs, renaming variables * Refactor: Fix failed build, when generated test case for recursion is too big. To avoid stackoverflow * Checkstyle: Adding newline to end of class * refactor: simplify assign minIndex in recursiveSelectionSort, and improving SelectionSort * checkstyle: adding newline to SelectionSort --------- Co-authored-by: Alex Klymenko <alx@alx.com> Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
This commit is contained in:
parent
0087444e9f
commit
20e7a3aca4
@ -1,46 +1,31 @@
|
|||||||
package com.thealgorithms.sorts;
|
package com.thealgorithms.sorts;
|
||||||
|
|
||||||
public class SelectionSort implements SortAlgorithm {
|
public class SelectionSort implements SortAlgorithm {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic selection sort algorithm in increasing order.
|
* Sorts an array of comparable elements in increasing order using the selection sort algorithm.
|
||||||
*
|
*
|
||||||
* @param arr the array to be sorted.
|
* @param array the array to be sorted
|
||||||
* @param <T> the class of array.
|
* @param <T> the class of array elements
|
||||||
* @return sorted array.
|
* @return the sorted array
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public <T extends Comparable<T>> T[] sort(T[] arr) {
|
public <T extends Comparable<T>> T[] sort(T[] array) {
|
||||||
int n = arr.length;
|
// One by one move the boundary of the unsorted subarray
|
||||||
for (int i = 0; i < n - 1; i++) {
|
for (int i = 0; i < array.length - 1; i++) {
|
||||||
int minIndex = i;
|
|
||||||
for (int j = i + 1; j < n; j++) {
|
// Swap the remaining minimum element with the current element
|
||||||
if (arr[minIndex].compareTo(arr[j]) > 0) {
|
SortUtils.swap(array, i, findIndexOfMin(array, i));
|
||||||
minIndex = j;
|
|
||||||
}
|
}
|
||||||
}
|
return array;
|
||||||
if (minIndex != i) {
|
|
||||||
SortUtils.swap(arr, i, minIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static <T extends Comparable<T>> int findIndexOfMin(T[] array, final int start) {
|
||||||
* Driver Code
|
int minIndex = start;
|
||||||
*/
|
for (int i = start + 1; i < array.length; i++) {
|
||||||
public static void main(String[] args) {
|
if (array[i].compareTo(array[minIndex]) < 0) {
|
||||||
Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12};
|
minIndex = i;
|
||||||
SelectionSort selectionSort = new SelectionSort();
|
|
||||||
Integer[] sorted = selectionSort.sort(arr);
|
|
||||||
for (int i = 0; i < sorted.length - 1; ++i) {
|
|
||||||
assert sorted[i] <= sorted[i + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] strings = {"c", "a", "e", "b", "d"};
|
|
||||||
String[] sortedStrings = selectionSort.sort(strings);
|
|
||||||
for (int i = 0; i < sortedStrings.length - 1; ++i) {
|
|
||||||
assert strings[i].compareTo(strings[i + 1]) <= 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return minIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,7 @@ public class SelectionSortRecursive implements SortAlgorithm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the minimum element in the remaining unsorted array
|
SortUtils.swap(array, index, findMinIndex(array, index));
|
||||||
final int minIndex = findMinIndex(array, index);
|
|
||||||
|
|
||||||
// Swap the found minimum element with the element at the current index
|
|
||||||
if (minIndex != index) {
|
|
||||||
SortUtils.swap(array, index, minIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursively call selection sort for the remaining array
|
// Recursively call selection sort for the remaining array
|
||||||
recursiveSelectionSort(array, index + 1);
|
recursiveSelectionSort(array, index + 1);
|
||||||
@ -47,20 +41,21 @@ public class SelectionSortRecursive implements SortAlgorithm {
|
|||||||
/**
|
/**
|
||||||
* Finds the index of the minimum element in the array starting from the given index.
|
* Finds the index of the minimum element in the array starting from the given index.
|
||||||
*
|
*
|
||||||
* @param array the array to search in.
|
* @param array the array to search
|
||||||
* @param start the starting index.
|
* @param start the starting index for the search
|
||||||
* @param <T> the type of the elements in the array, which must be Comparable.
|
* @param <T> the type of elements in the array
|
||||||
* @return the index of the minimum element starting from the given index.
|
* @return the index of the minimum element
|
||||||
*/
|
*/
|
||||||
private static <T extends Comparable<T>> int findMinIndex(T[] array, int start) {
|
private static <T extends Comparable<T>> int findMinIndex(T[] array, int start) {
|
||||||
int currentMinIndex = start;
|
// Base case: if start is the last index, return start
|
||||||
|
if (start == array.length - 1) {
|
||||||
for (int currentIndex = start + 1; currentIndex < array.length; currentIndex++) {
|
return start;
|
||||||
if (array[currentIndex].compareTo(array[currentMinIndex]) < 0) {
|
|
||||||
currentMinIndex = currentIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentMinIndex;
|
// Recursive call to find the minimum index in the rest of the array
|
||||||
|
final int minIndexInRest = findMinIndex(array, start + 1);
|
||||||
|
|
||||||
|
// Return the index of the smaller element between array[start] and the minimum element in the rest of the array
|
||||||
|
return array[start].compareTo(array[minIndexInRest]) < 0 ? start : minIndexInRest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,8 @@ public class SelectionSortRecursiveTest extends SortingAlgorithmTest {
|
|||||||
SortAlgorithm getSortAlgorithm() {
|
SortAlgorithm getSortAlgorithm() {
|
||||||
return new SelectionSortRecursive();
|
return new SelectionSortRecursive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int getGeneratedArraySize() {
|
||||||
|
return 5000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,8 @@
|
|||||||
package com.thealgorithms.sorts;
|
package com.thealgorithms.sorts;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
class SelectionSortTest extends SortingAlgorithmTest {
|
||||||
|
@Override
|
||||||
import org.junit.jupiter.api.Test;
|
SortAlgorithm getSortAlgorithm() {
|
||||||
|
return new SelectionSort();
|
||||||
class SelectionSortTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
// valid test case
|
|
||||||
void integerArrTest() {
|
|
||||||
Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12};
|
|
||||||
SelectionSort selectionSort = new SelectionSort();
|
|
||||||
|
|
||||||
assertArrayEquals(new Integer[] {1, 4, 6, 9, 12, 23, 54, 78, 231}, selectionSort.sort(arr));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
// valid test case
|
|
||||||
void stringArrTest() {
|
|
||||||
String[] arr = {"c", "a", "e", "b", "d"};
|
|
||||||
SelectionSort selectionSort = new SelectionSort();
|
|
||||||
|
|
||||||
assertArrayEquals(new String[] {"a", "b", "c", "d", "e"}, selectionSort.sort(arr));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
// invalid test case
|
|
||||||
void emptyArrTest() {
|
|
||||||
Integer[] arr = {};
|
|
||||||
SelectionSort selectionSort = new SelectionSort();
|
|
||||||
|
|
||||||
assertArrayEquals(new Integer[] {}, selectionSort.sort(arr));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,10 @@ import org.junit.jupiter.api.Test;
|
|||||||
public abstract class SortingAlgorithmTest {
|
public abstract class SortingAlgorithmTest {
|
||||||
abstract SortAlgorithm getSortAlgorithm();
|
abstract SortAlgorithm getSortAlgorithm();
|
||||||
|
|
||||||
|
protected int getGeneratedArraySize() {
|
||||||
|
return 10_000;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldAcceptWhenEmptyArrayIsPassed() {
|
void shouldAcceptWhenEmptyArrayIsPassed() {
|
||||||
Integer[] array = new Integer[] {};
|
Integer[] array = new Integer[] {};
|
||||||
@ -153,7 +157,7 @@ public abstract class SortingAlgorithmTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldAcceptWhenRandomArrayIsPassed() {
|
void shouldAcceptWhenRandomArrayIsPassed() {
|
||||||
int randomSize = SortUtilsRandomGenerator.generateInt(10_000);
|
int randomSize = SortUtilsRandomGenerator.generateInt(getGeneratedArraySize());
|
||||||
Double[] array = SortUtilsRandomGenerator.generateArray(randomSize);
|
Double[] array = SortUtilsRandomGenerator.generateArray(randomSize);
|
||||||
Double[] sorted = getSortAlgorithm().sort(array);
|
Double[] sorted = getSortAlgorithm().sort(array);
|
||||||
assertTrue(SortUtils.isSorted(sorted));
|
assertTrue(SortUtils.isSorted(sorted));
|
||||||
@ -161,7 +165,7 @@ public abstract class SortingAlgorithmTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldAcceptWhenRandomListIsPassed() {
|
void shouldAcceptWhenRandomListIsPassed() {
|
||||||
int randomSize = SortUtilsRandomGenerator.generateInt(10_000);
|
int randomSize = SortUtilsRandomGenerator.generateInt(getGeneratedArraySize());
|
||||||
Double[] array = SortUtilsRandomGenerator.generateArray(randomSize);
|
Double[] array = SortUtilsRandomGenerator.generateArray(randomSize);
|
||||||
List<Double> list = List.of(array);
|
List<Double> list = List.of(array);
|
||||||
List<Double> sorted = getSortAlgorithm().sort(list);
|
List<Double> sorted = getSortAlgorithm().sort(list);
|
||||||
|
Loading…
Reference in New Issue
Block a user