我有一个列表数组(array<list<Client*>, 10>
),我希望看到哪个列表中的项目数最少,所以我可以添加它。我在这里做一个小型平衡系统,当客户进来时,我想将它们添加到1个或10个列表中,其他客户端数量最少,以保持列表级别。
我是否必须在此处进行冒泡排序,或者是否有一些很好的方式来处理这样的事情?
答案 0 :(得分:5)
这正是std::min_element
的用途:
std::array<std::list<Client*>, 10> arr;
auto it = std::min_element(arr.begin(), arr.end(),
[](const std::list<Client*>& a, const std::list<Client*>& b){
return a.size() < b.size();
});
那将给你一个迭代器,其中list
具有最少的元素。
答案 1 :(得分:5)
如果列表在您开始添加时从零元素开始,并且您希望保持它们完美平衡,请考虑只添加循环样式列表:
伪代码:
index = 0
list to add to = lists[index % list length]
index++
答案 2 :(得分:1)
如果您确实需要对其进行排序,以便首先显示项目数最少的列表(而不是std::min_element
来简单地获取最低项目,例如Barry suggested),那么您可以使用{{3} },例如:
std::array<int,10> myArray{10,9,8,7,6,5,4,3,2,1};
std::partial_sort(myArray.begin(),myArray.begin()+1,myArray.end(),
[](const int& lhs, const int& rhs){return lhs < rhs;});
这里的最后一个参数是lambda用于比较。你可以用
之类的东西替换它[](const list<Client*>& lhs, const list<Client*>& rhs){return lhs.size() < rhs.size();)
答案 3 :(得分:1)
如果以相同的速率为所有客户端提供服务(从列表中删除),那么循环调度就是明显的答案。
但是,如果存在可变性(例如,您正在模拟占用不同时间的客户),您可能需要类似于集合的优先级队列,使用每个集合的长度作为优先级。这将把当前最高优先级项(最短列表)放在已知位置(通常是队列中的第一项)。插入新项目后,您(可能)&#34;筛选&#34;在堆中保持堆属性。
这允许您插入或删除具有O(log N)复杂度的项目,其中std::min_element
之类的内容需要O(N)复杂度。
顺便说一句:如果你关心速度,那么list
也不是一个很好的选择。列表具有单独分配的节点,每个节点包含两个指针。这些因素往往导致参考的局部性较差,这通常意味着缓存使用率较低。而不是一个向量的priority_queue(只有一种可能性)通常会更好。