Skip to content

Commit c4eede7

Browse files
author
alxklm
committed
feat: PatienceSort
1 parent 2d6c39c commit c4eede7

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
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)
@@ -876,6 +877,7 @@
876877
* [MergeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortTest.java)
877878
* [OddEvenSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java)
878879
* [PancakeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java)
880+
* [PatienceSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PatienceSortTest.java)
879881
* [QuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/QuickSortTest.java)
880882
* [SelectionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java)
881883
* [SelectionSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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; // bitwise complement, which is equivalent to (-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+
if (!pile.isEmpty()) {
79+
pq.add(new PileNode<>(pile.removeLast(), pile));
80+
}
81+
}
82+
return pq;
83+
}
84+
85+
/**
86+
* Extracts elements from the priority queue to form the sorted array.
87+
*
88+
* @param array the array to be filled with sorted elements
89+
* @param pq the priority queue containing the elements to be extracted
90+
* @param <T> the type of elements in the array, must be comparable
91+
*/
92+
private static <T extends Comparable<T>> void extractPiles(final T[] array, final PriorityQueue<PileNode<T>> pq) {
93+
int index = 0;
94+
while (!pq.isEmpty()) {
95+
PileNode<T> node = pq.poll();
96+
array[index++] = node.value;
97+
if (!node.pile.isEmpty()) {
98+
pq.add(new PileNode<>(node.pile.removeLast(), node.pile));
99+
}
100+
}
101+
}
102+
103+
/**
104+
* A helper record representing a node in the priority queue.
105+
*
106+
* @param <T> the type of elements in the node, must be comparable
107+
*/
108+
private record PileNode<T extends Comparable<T>>(T value, List<T> pile) implements Comparable<PileNode<T>> {
109+
@Override
110+
public int compareTo(PileNode<T> other) {
111+
return this.value.compareTo(other.value);
112+
}
113+
}
114+
}
Lines changed: 8 additions & 0 deletions
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)