Refactoring and code improving for StrandSort (#5243)

* Refactoring and code improving for StrandSort

* Fix java checkstyle

* Fix "Each variable declaration must be in its own statement"

* Fix "uses integer based for loops to iterate over a List"

---------

Co-authored-by: alx <alx@alx.com>
This commit is contained in:
Alex K 2024-06-20 18:47:43 +03:00 committed by GitHub
parent 91101ec424
commit 15d2e70673
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 62 additions and 55 deletions

View File

@ -1,46 +1,79 @@
package com.thealgorithms.sorts;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public final class StrandSort {
private StrandSort() {
/**
* StrandSort class implementing the SortAlgorithm interface using arrays.
*/
public final class StrandSort implements SortAlgorithm {
/**
* Sorts the given array using the Strand Sort algorithm.
*
* @param <T> The type of elements to be sorted, must be Comparable.
* @param unsorted The array to be sorted.
* @return The sorted array.
*/
@Override
public <T extends Comparable<T>> T[] sort(T[] unsorted) {
List<T> unsortedList = new ArrayList<>(Arrays.asList(unsorted));
List<T> sortedList = strandSort(unsortedList);
return sortedList.toArray(unsorted);
}
// note: the input list is destroyed
public static <E extends Comparable<? super E>> LinkedList<E> strandSort(LinkedList<E> list) {
/**
* Strand Sort algorithm that sorts a list.
*
* @param <T> The type of elements to be sorted, must be Comparable.
* @param list The list to be sorted.
* @return The sorted list.
*/
private static <T extends Comparable<? super T>> List<T> strandSort(List<T> list) {
if (list.size() <= 1) {
return list;
}
LinkedList<E> result = new LinkedList<E>();
while (list.size() > 0) {
LinkedList<E> sorted = new LinkedList<E>();
sorted.add(list.removeFirst()); // same as remove() or remove(0)
for (Iterator<E> it = list.iterator(); it.hasNext();) {
E elem = it.next();
if (sorted.peekLast().compareTo(elem) <= 0) {
sorted.addLast(elem); // same as add(elem) or add(0, elem)
it.remove();
List<T> result = new ArrayList<>();
while (!list.isEmpty()) {
final List<T> sorted = new ArrayList<>();
sorted.add(list.remove(0));
for (int i = 0; i < list.size();) {
if (sorted.get(sorted.size() - 1).compareTo(list.get(i)) <= 0) {
sorted.add(list.remove(i));
} else {
i++;
}
}
result = merge(sorted, result);
result = merge(result, sorted);
}
return result;
}
private static <E extends Comparable<? super E>> LinkedList<E> merge(LinkedList<E> left, LinkedList<E> right) {
LinkedList<E> result = new LinkedList<E>();
while (!left.isEmpty() && !right.isEmpty()) {
// change the direction of this comparison to change the direction of the sort
if (left.peek().compareTo(right.peek()) <= 0) {
result.add(left.remove());
/**
* Merges two sorted lists into one sorted list.
*
* @param <T> The type of elements to be sorted, must be Comparable.
* @param left The first sorted list.
* @param right The second sorted list.
* @return The merged sorted list.
*/
private static <T extends Comparable<? super T>> List<T> merge(List<T> left, List<T> right) {
List<T> result = new ArrayList<>();
int i = 0;
int j = 0;
while (i < left.size() && j < right.size()) {
if (left.get(i).compareTo(right.get(j)) <= 0) {
result.add(left.get(i));
i++;
} else {
result.add(right.remove());
result.add(right.get(j));
j++;
}
}
result.addAll(left);
result.addAll(right);
result.addAll(left.subList(i, left.size()));
result.addAll(right.subList(j, right.size()));
return result;
}
}

View File

@ -1,34 +1,8 @@
package com.thealgorithms.sorts;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import java.util.Arrays;
import java.util.LinkedList;
import org.junit.jupiter.api.Test;
class StrandSortTest {
@Test
// valid test case
public void strandSortNonDuplicateTest() {
int[] expectedArray = {1, 2, 3, 4, 5};
LinkedList<Integer> actualList = StrandSort.strandSort(new LinkedList<Integer>(Arrays.asList(3, 1, 2, 4, 5)));
int[] actualArray = new int[actualList.size()];
for (int i = 0; i < actualList.size(); i++) {
actualArray[i] = actualList.get(i);
}
assertArrayEquals(expectedArray, actualArray);
}
@Test
// valid test case
public void strandSortDuplicateTest() {
int[] expectedArray = {2, 2, 2, 5, 7};
LinkedList<Integer> actualList = StrandSort.strandSort(new LinkedList<Integer>(Arrays.asList(7, 2, 2, 2, 5)));
int[] actualArray = new int[actualList.size()];
for (int i = 0; i < actualList.size(); i++) {
actualArray[i] = actualList.get(i);
}
assertArrayEquals(expectedArray, actualArray);
class StrandSortTest extends SortingAlgorithmTest {
@Override
SortAlgorithm getSortAlgorithm() {
return new StrandSort();
}
}