📜  耐心排序

📅  最后修改于: 2021-10-26 05:32:12             🧑  作者: Mango

Patience排序是一种基于纸牌游戏Patience的排序算法。在这个排序算法中,耐心游戏规则用于根据元素的值对元素列表进行排序。
耐心游戏规则:

  • 价值较低的卡片可以放在卡片上。
  • 如果卡片没有可能的位置,则可以创建一个新堆。
  • 目标是形成尽可能少的桩。

下面是游戏的可视化如下:

如上图所示,很明显只有当卡片的价值小于堆中最高的卡片时才会放置卡片。否则,如果没有这样的桩,则创建一个新桩。
耐心排序:耐心排序通常有两个步骤,即创建堆和合并堆。下面是步骤的图示:

  • 初始化一个二维数组来存储桩。
  • 遍历给定数组并执行以下操作:
    1. 遍历所有堆并检查每堆的堆栈顶部是否小于当前元素。如果发现为真,则将当前元素压入栈顶。
    2. 否则,以当前元素作为该堆栈的顶部创建一个新堆。
  • 合并桩:这个想法是对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 现场工作专业课程学生竞争性编程现场课程