2

I have an array of lists (array<list<Client*>, 10>) and I want to see which list has the lowest item count in it so I can add to that. I'm doing a small balancing system here and as clients come in I want to add them to 1 or the 10 lists which has the lowest number of other clients to keep the lists level.

Would I have to do a bubble sort here or is there some sweet stl way to handle something like this?

0

4 Answers 4

5

That's precisely what std::min_element is for:

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();
          });

That'll give you an iterator into which list has the fewest elements.

Sign up to request clarification or add additional context in comments.

Comments

5

If the lists start at zero elements when you start adding to them and you want to keep them perfectly balanced, consider just adding to the lists round robin style:

Pseudo Code:

index = 0
list to add to = lists[index % list length]
index++

2 Comments

So much better than everything else. Lateral thinking > *
Yes. I approve of this style of XY-answering.
1

If you actually need it sorted such that the list with the lowest item count appears first (and not std::min_element to simply get the lowest item like Barry suggested), then you could use std::partial_sort, e.g.:

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;});

Where the last parameter here is a lambda for comparison. You'd replace it with something like

[](const list<Client*>& lhs, const list<Client*>& rhs){return lhs.size() < rhs.size();)

Live Demo

Comments

1

If all the clients are serviced (removed from the lists) at the same rate, then round-robin scheduling is the obvious answer.

If, however, there's variability (e.g., you're simulating customers who take different lengths of time) you probably want something like a priority queue of collections, using the length of each collection as the priority. This will place the current highest priority item (shortest list) in a known location (usually the first item in the queue). After you insert a new item, you (potentially ) "sift" that down the heap to maintain the heap property.

This allows you to insert or remove an item with O(log N) complexity, where something like std::min_element would require O(N) complexity.

As an aside: if you care about speed, chances are pretty good that list isn't a great choice either. A list has individually allocated nodes, and each node contains two pointers. These factors tend to lead to poor locality of reference, which generally implies poor cache usage. A priority_queue of vectors instead (for only one possibility) will often work better.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.