Patience排序是一种基于纸牌游戏Patience的排序算法。在这个排序算法中,耐心游戏规则用于根据元素的值对元素列表进行排序。
耐心游戏规则:
- 价值较低的卡片可以放在卡片上。
- 如果卡片没有可能的位置,则可以创建一个新堆。
- 目标是形成尽可能少的桩。
下面是游戏的可视化如下:
如上图所示,很明显只有当卡片的价值小于堆中最高的卡片时才会放置卡片。否则,如果没有这样的桩,则创建一个新桩。
耐心排序:耐心排序通常有两个步骤,即创建堆和合并堆。下面是步骤的图示:
- 初始化一个二维数组来存储桩。
- 遍历给定数组并执行以下操作:
- 遍历所有堆并检查每堆的堆栈顶部是否小于当前元素。如果发现为真,则将当前元素压入栈顶。
- 否则,以当前元素作为该堆栈的顶部创建一个新堆。
- 合并桩:这个想法是对p桩执行k路合并,每个桩都在内部排序。遍历所有的堆,当堆中元素的计数大于或等于0 时,从每个堆栈的顶部找到最小的元素并将其推入已排序的数组。
以下是排序步骤的可视化:
下面是上述方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Function to merge piles in a sorted order
vector merge_piles(vector >& v)
{
// Store minimum element from
// the top of stack
vector ans;
// In every iteration find the smallest element
// of top of pile and remove it from the piles
// and store into the final array
while (1) {
// Stores the smallest element
// of the top of the piles
int minu = INT_MAX;
// Stores index of the smallest element
// of the top of the piles
int index = -1;
// Calculate the smallest element
// of the top of the every stack
for (int i = 0; i < v.size(); i++) {
// If minu is greater than
// the top of the current stack
if (minu > v[i][v[i].size() - 1]) {
// Update minu
minu = v[i][v[i].size() - 1];
// Update index
index = i;
}
}
// Insert the smallest element
// of the top of the stack
ans.push_back(minu);
// Remove the top element from
// the current pile
v[index].pop_back();
// If current pile is empty
if (v[index].empty()) {
// Remove current pile
// from all piles
v.erase(v.begin() + index);
}
// If all the piles are empty
if (v.size() == 0)
break;
}
return ans;
}
// Function to sort the given array
// using the patience sorting
vector patienceSorting(vector arr)
{
// Store all the created piles
vector > piles;
// Traverse the array
for (int i = 0; i < arr.size(); i++) {
// If no piles are created
if (piles.empty()) {
// Initialize a new pile
vector temp;
// Insert current element
// into the pile
temp.push_back(arr[i]);
// Insert current pile into
// all the piles
piles.push_back(temp);
}
else {
// Check if top element of each pile
// is less than or equal to
// current element or not
int flag = 1;
// Traverse all the piles
for (int j = 0; j < piles.size(); j++) {
// Check if the element to be
// inserted is less than
// current pile's top
if (arr[i] < piles[j][piles[j].size() - 1]) {
piles[j].push_back(arr[i]);
// Update flag
flag = 0;
break;
}
}
// If flag is true
if (flag) {
// Create a new pile
vector temp;
// Insert current element
// into temp
temp.push_back(arr[i]);
// Insert current pile
// into all the piles
piles.push_back(temp);
}
}
}
// Store the sorted sequence
// of the given array
vector ans;
// Sort the given array
ans = merge_piles(piles);
// Traverse the array, ans[]
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << " ";
return ans;
}
// Driver Code
int main()
{
vector arr = { 6, 12, 2, 8, 3, 7 };
// Function Call
patienceSorting(arr);
}
Javascript
2 3 6 7 8 12
时间复杂度: O(N 2 )
辅助空间: O(N)
注意:可以通过使用priority_queue合并堆来优化上述方法。
时间复杂度: O(N * log(N))
辅助空间: O(N)
函数 playGif(){ var gif = document.getElementById(‘gif’); if (gif.src == “https://media.geeksforgeeks.org/wp-content/uploads/20200501171647/Patience.gif”){ gif.src = “https://media .geeksforgeeks.org/wp-content/uploads/20200501175532/base2.jpg”; }else{ gif.src = “https://media.geeksforgeeks.org/wp-content/uploads/20200501171647/Patience.gif”; } } 函数 playSortingGif(){ var gif1 = document.getElementById(‘sorting’); var gif2 = document.getElementById(‘sorting_gif1’); gif1.style.display = “无”; gif2.style.display = “块”; }函数pauseSortingGif(){ var gif1 = document.getElementById(‘sorting’); var gif2 = document.getElementById(‘sorting_gif1’); gif1.style.display = “块”; gif2.style.display = “无”; }
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。