Skip to content

Commit 76a450f

Browse files
alxkmalxklm
and
alxklm
authored
feat: add PatienceSort (#5288)
* feat: PatienceSort * refactor: fix readability issues,a and redundant check --------- Co-authored-by: alxklm <[email protected]>
1 parent 08db744 commit 76a450f

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

DIRECTORY.md

+2
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@
511511
* [MergeSortRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java)
512512
* [OddEvenSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/OddEvenSort.java)
513513
* [PancakeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PancakeSort.java)
514+
* [PatienceSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PatienceSort.java)
514515
* [PigeonholeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java)
515516
* [QuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/QuickSort.java)
516517
* [RadixSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/RadixSort.java)
@@ -881,6 +882,7 @@
881882
* [MergeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortTest.java)
882883
* [OddEvenSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java)
883884
* [PancakeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java)
885+
* [PatienceSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PatienceSortTest.java)
884886
* [QuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/QuickSortTest.java)
885887
* [RadixSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/RadixSortTest.java)
886888
* [SelectionSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.thealgorithms.sorts;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import java.util.PriorityQueue;
7+
8+
/**
9+
* This class implements the Patience Sort algorithm. Patience Sort is a sorting algorithm that
10+
* is particularly good for sorting sequences that are already partially sorted.
11+
*/
12+
public class PatienceSort implements SortAlgorithm {
13+
14+
/**
15+
* Sorts an array of comparable elements using the Patience Sort algorithm.
16+
*
17+
* @param array the array to be sorted
18+
* @param <T> the type of elements in the array, must be comparable
19+
* @return the sorted array
20+
*/
21+
@Override
22+
public <T extends Comparable<T>> T[] sort(T[] array) {
23+
if (array.length == 0) {
24+
return array;
25+
}
26+
27+
final List<List<T>> piles = formPiles(array);
28+
final PriorityQueue<PileNode<T>> pq = mergePiles(piles);
29+
extractPiles(array, pq);
30+
31+
return array;
32+
}
33+
34+
/**
35+
* Forms piles from the given array. Each pile is a list of elements where
36+
* each element is smaller than the one before it. Binary search is used
37+
* to find the appropriate pile for each element.
38+
*
39+
* @param array the array of elements to be organized into piles
40+
* @param <T> the type of elements in the array, must be comparable
41+
* @return a list of piles
42+
*/
43+
private static <T extends Comparable<T>> List<List<T>> formPiles(final T[] array) {
44+
final List<List<T>> piles = new ArrayList<>();
45+
final List<T> lastElements = new ArrayList<>();
46+
47+
for (T x : array) {
48+
int pos = Collections.binarySearch(lastElements, x);
49+
if (pos < 0) {
50+
pos = -pos - 1;
51+
}
52+
53+
if (pos < piles.size()) {
54+
piles.get(pos).add(x);
55+
lastElements.set(pos, x);
56+
} else {
57+
List<T> newPile = new ArrayList<>();
58+
newPile.add(x);
59+
piles.add(newPile);
60+
lastElements.add(x);
61+
}
62+
}
63+
64+
return piles;
65+
}
66+
67+
/**
68+
* Merges the piles into a priority queue where the smallest elements are
69+
* prioritized.
70+
*
71+
* @param piles the list of piles to be merged
72+
* @param <T> the type of elements in the piles, must be comparable
73+
* @return a priority queue containing the top element of each pile
74+
*/
75+
private static <T extends Comparable<T>> PriorityQueue<PileNode<T>> mergePiles(final List<List<T>> piles) {
76+
PriorityQueue<PileNode<T>> pq = new PriorityQueue<>();
77+
for (List<T> pile : piles) {
78+
pq.add(new PileNode<>(pile.removeLast(), pile));
79+
}
80+
return pq;
81+
}
82+
83+
/**
84+
* Extracts elements from the priority queue to form the sorted array.
85+
*
86+
* @param array the array to be filled with sorted elements
87+
* @param pq the priority queue containing the elements to be extracted
88+
* @param <T> the type of elements in the array, must be comparable
89+
*/
90+
private static <T extends Comparable<T>> void extractPiles(final T[] array, final PriorityQueue<PileNode<T>> pq) {
91+
int index = 0;
92+
while (!pq.isEmpty()) {
93+
PileNode<T> node = pq.poll();
94+
array[index++] = node.value;
95+
if (!node.pile.isEmpty()) {
96+
pq.add(new PileNode<>(node.pile.removeLast(), node.pile));
97+
}
98+
}
99+
}
100+
101+
/**
102+
* A helper record representing a node in the priority queue.
103+
*
104+
* @param <T> the type of elements in the node, must be comparable
105+
*/
106+
private record PileNode<T extends Comparable<T>>(T value, List<T> pile) implements Comparable<PileNode<T>> {
107+
@Override
108+
public int compareTo(PileNode<T> other) {
109+
return this.value.compareTo(other.value);
110+
}
111+
}
112+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.thealgorithms.sorts;
2+
3+
public class PatienceSortTest extends SortingAlgorithmTest {
4+
@Override
5+
SortAlgorithm getSortAlgorithm() {
6+
return new PatienceSort();
7+
}
8+
}

0 commit comments

Comments
 (0)