# What is Patience Sort

**is a sorting algorithm that's used to sort a collection of items into a specific order. It's based on the idea of organizing the items into "piles" based on their value, and then merging those piles together to create the final sorted list.**

Patience sort

Patience sort

To start, the algorithm takes the first item in the collection and creates a new pile with just that item. Then it compares the next item to the top item in each pile and adds the item to the pile with the smallest top item. If there are multiple piles with the same top item, it chooses the leftmost pile. If the new item is larger than the top item in all piles, it creates a new pile with just that item.

The process continues with each new item in the collection until all items have been added to a pile. Then the piles are merged together, starting with the smallest top items and adding them to a new sorted list. This process continues until all items have been added to the sorted list.

Overall, Patience sort is a relatively efficient algorithm that's especially useful for sorting items in a specific order, such as alphabetically or by date. It's named after the game of solitaire, where players organize cards into "piles" based on their value.

## Who invented it?

**Patience sort**was invented by a computer scientist named Eugene W. Myers in 1985. Myers is known for his work on algorithm development and bioinformatics, and he created Patience sort as a way to efficiently solve a specific problem in his work on sequence alignment.

The name "Patience" comes from the card game Solitaire, which involves organizing cards into piles in a similar way to how Patience sort organizes items. Myers chose the name because he thought the process of sorting items using this algorithm required a certain amount of patience and careful organization, much like playing a game of Solitaire.

## Pseudocode

```
function patience_sort(collection):
piles = []
for item in collection:
new_pile = [item]
for pile in piles:
if item < pile[-1]:
pile.append(item)
break
else:
piles.append(new_pile)
sorted_list = []
while piles:
smallest_pile = min(piles, key=lambda pile: pile[-1])
sorted_list.append(smallest_pile.pop())
if not smallest_pile:
piles.remove(smallest_pile)
return sorted_list
```

In this implementation, collection is the unsorted list of items, and patience_sort returns the sorted list. The algorithm uses a list of piles to keep track of items as they're sorted, and then iterates through each item in the collection.

For each item, the algorithm creates a new pile with just that item and compares it to each existing pile in piles. If the item is smaller than the top item in a pile, the item is added to that pile and the loop continues with the next item. If the item is larger than the top item in all piles, the algorithm creates a new pile with just that item and adds it to piles.

Once all items have been added to piles, the algorithm creates a new list sorted_list and starts merging piles together by selecting the smallest top item from all the piles, adding it to sorted_list, and removing it from its pile. When all the items have been added to sorted_list, it is returned as the final sorted result.

For each item, the algorithm creates a new pile with just that item and compares it to each existing pile in piles. If the item is smaller than the top item in a pile, the item is added to that pile and the loop continues with the next item. If the item is larger than the top item in all piles, the algorithm creates a new pile with just that item and adds it to piles.

Once all items have been added to piles, the algorithm creates a new list sorted_list and starts merging piles together by selecting the smallest top item from all the piles, adding it to sorted_list, and removing it from its pile. When all the items have been added to sorted_list, it is returned as the final sorted result.

## Sample Code

```
// C++ code snippet
vector
```> patience_sort(vector collection) {
vector> piles; // A vector of piles of cards
for (int item : collection) {
vector new_pile = { item };
for (vector& pile : piles) {
if (item < pile.back()) { // If the item is smaller than the last card in the pile
pile.push_back(item); // Add the item to the pile
goto next_item; // Go to the next item in the collection
}
}
piles.push_back(new_pile); // If the item is larger than all the piles, create a new pile for it
next_item:;
}
vector> sorted_piles; // A vector of sorted piles
for (int item : collection) {
int pile_idx = 0;
while (pile_idx < sorted_piles.size() && item >= sorted_piles[pile_idx].back()) {
pile_idx++;
}
sorted_piles[pile_idx].push_back(item);
}
return sorted_piles;
}
int main() {
vector unsorted = { 5, 3, 9, 7, 1, 8, 4, 6, 2 };
vector> sorted_piles = patience_sort(unsorted);
vector sorted;
for (vector& pile : sorted_piles) {
sorted.insert(sorted.end(), pile.begin(), pile.end());
}
for (int item : sorted) {
cout << item << " ";
}
return 0;
}

```
# Python code snippet
def patience_sort(collection):
piles = [] # A list of piles of cards
for item in collection:
new_pile = [item]
for pile in piles:
if item < pile[-1]: # If the item is smaller than the last card in the pile
pile.append(item) # Add the item to the pile
break
else:
piles.append(new_pile) # If the item is larger than all the piles, create a new pile for it
sorted_list = [] # A list of sorted cards
while piles:
smallest_pile = min(piles, key=lambda pile: pile[-1]) # Find the smallest pile by comparing the last cards
sorted_list.append(smallest_pile.pop()) # Remove the last card from the smallest pile and add it to the sorted list
if not smallest_pile: # If the smallest pile is empty, remove it from the list of piles
piles.remove(smallest_pile)
return sorted_list
```

```
import java.util.ArrayList;
import java.util.List;
public class PatienceSort {
public static List
```> patienceSort(List collection) {
List> piles = new ArrayList<>(); // A list of piles of cards
for (int item : collection) {
List newPile = new ArrayList<>();
newPile.add(item);
for (List pile : piles) {
if (item < pile.get(pile.size() - 1)) { // If the item is smaller than the last card in the pile
pile.add(item); // Add the item to the pile
newPile = null;
break;
}
}
if (newPile != null) {
piles.add(newPile); // If the item is larger than all the piles, create a new pile for it
}
}
List> sortedPiles = new ArrayList<>(); // A list of sorted piles
for (int item : collection) {
int pileIndex = 0;
while (pileIndex < sortedPiles.size() && item >= sortedPiles.get(pileIndex).get(sortedPiles.get(pileIndex).size() - 1)) {
pileIndex++;
}
if (pileIndex == sortedPiles.size()) {
sortedPiles.add(new ArrayList<>());
}
sortedPiles.get(pileIndex).add(item);
}
return sortedPiles;
}
public static void main(String[] args) {
List unsorted = List.of(5, 3, 9, 7, 1, 8, 4, 6, 2);
List> sortedPiles = patienceSort(unsorted);
List sorted = new ArrayList<>();
for (List pile : sortedPiles) {
sorted.addAll(pile);
}
for (int item : sorted) {
System.out.print(item + " ");
}
}
}

## Time and Space Complexity

- The time complexity of Patience sort is O(n log n), where n is the number of elements to be sorted. This is because the algorithm involves creating piles of cards, and the number of piles created is at most log n. Since we iterate through each element in the input list at most twice (once to create the piles and once to merge the sorted piles), the time complexity is O(n log n).
- The space complexity of Patience sort is also O(n), where n is the number of elements to be sorted. This is because we need to create a new pile for each element in the input list, and the total number of piles created is at most n. Additionally, we need to store the sorted piles in memory until we merge them into a single sorted list. Therefore, the space complexity of Patience sort is O(n).

## Advantages

- Patience sort is a stable sorting algorithm, meaning that it preserves the relative order of equal elements in the input list. This is important in certain applications where the order of equal elements needs to be preserved.
- Patience sort can handle large or small elements with equal ease, unlike some other sorting algorithms that may have trouble with extremely small or large elements.
- The algorithm is simple to understand and implement, making it a good choice for small to medium-sized input sizes.

## Disadvantages

- Patience sort has a space complexity of O(n), which may be a disadvantage for very large input sizes where memory is limited.
- The worst-case time complexity of Patience sort is O(n log n), which is the same as many other comparison-based sorting algorithms like Merge sort and Quick sort. This means that Patience sort may not be the fastest algorithm for very large input sizes, especially when the input is already partially sorted.
- Patience sort is not an in-place sorting algorithm, meaning that it requires extra memory to perform the sorting operation. This may be a disadvantage in situations where memory is limited or expensive.