如何制作按第二个元素排序的最小元组堆?

Posted

技术标签:

【中文标题】如何制作按第二个元素排序的最小元组堆?【英文标题】:How to make a min heap of tuples sorted by the 2nd element? 【发布时间】:2020-11-11 15:04:19 【问题描述】:

所以我可以通过执行以下操作来创建最小堆:

// Creates a min heap
priority_queue <int, vector<int>, greater<int> > pq;
pq.push(5);
pq.push(1);
pq.push(10);
pq.push(30);
pq.push(20);

// One by one extract items from min heap
while (pq.empty() == false)

    cout << pq.top() << " ";
    pq.pop();


return 0;

但是如果我的堆是一对整数的元组并且我想按第二个元素排序呢?

例如

priority_queue<tuple<int,int>, vector<tuple<int,int>>> pq;
pq.push(make_tuple(3,2));
pq.push(make_tuple(4,9));
pq.push(make_tuple(1,5));

【问题讨论】:

看std::priority_queue上使用lambda的例子 比较器是std::priority_queue的模板参数 【参考方案1】:

您可以使用 std::get 按第二个元素进行比较:

int main()

    auto cmp = [](const std::tuple<int,int>& left, const std::tuple<int,int>& right)
        
            return std::get<1>(left) > std::get<1>(right);
        ;
    std::priority_queue<std::tuple<int,int>, std::vector<std::tuple<int,int>>, decltype(cmp)> pq(cmp);
    pq.push(std::make_tuple(3,2));
    pq.push(std::make_tuple(4,9));
    pq.push(std::make_tuple(1,5));
    while (pq.empty() == false)
    
        std::cout << std::get<1>(pq.top()) << std::endl;
        pq.pop();
    
    return 0;

预期输出:

2
5
9

【讨论】:

【参考方案2】:

您可以通过两种方式做到这一点:

    更改元组的顺序,使要排序的列是元组中的第一个。

    在您的函数定义之外创建一个自定义比较器。

     Struct Comparator 
        bool operator()(tuple<int, int>& t1, tuple<int, int>& t2) 
             return std::get<1>(t1) > std::get<1>(t2);
         
     
    

然后,你可以使用这个比较器来代替更大的>:

    priority_queue<tuple<int, int>, vector<tuple<int, int>>, Comparator> pq;

当您处理复杂的对象并希望按特定属性排序时,这非常方便。

【讨论】:

以上是关于如何制作按第二个元素排序的最小元组堆?的主要内容,如果未能解决你的问题,请参考以下文章

python 排序 sorted 如果第一个条件 相同 则按第二个条件排序

使用 itertools 按第二个值对连续元组进行分组

元组对,使用 python 找到最小值

orderByChild() 如果值相同,如何按第二个变量排序?

如何按第二个单词对列表进行排序? [复制]

MYSQL先按第一个字段排序,若相同再按第二个字段排序,如何实现?