Skip to content

Refactoring and code improving for StrandSort #5243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 58 additions & 25 deletions src/main/java/com/thealgorithms/sorts/StrandSort.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
34 changes: 4 additions & 30 deletions src/test/java/com/thealgorithms/sorts/StrandSortTest.java
Original file line number Diff line number Diff line change
@@ -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();
}
}