- Language: C++
One thing I can do is allocate a vector of size n and store all data and then sort it using sort(begin(),end()). Else, I can keep putting the data in a map or set which are ordered itself so I don't have to sort afterwards. But in this case inserting an element may be more costly due to rearrangements(I guess).
So which is the optimal choice for minimal time for a wide range of n(no. of objects)

- 1,368
- 5
- 18

- 408
- 3
- 12
-
2This is a data structures question. In an `std::set` or `std::map`, there is a balanced tree, which is sorted all the time - each insertion/deletion costs `O(logn)` which means the total insertions will cost `O(nlogn)`. While in a vector, each insertion will cost you `O(1)` (in average, because it sometimes must be duplicated), while each deletion will cost you `O(n)` and sorting it will cost you `O(nlogn)` **each time**. If you need it sorted all the time, I'd say clearly you should use a tree. Otherwise, it may be just the same as using a vector and sorting it in the end – SomethingSomething May 06 '18 at 10:57
-
You need to measure it. For example: which is faster to insert random ints into and keep the container sorted a map, a list or a vector? Answer in 2 mins when I find the presentation. – Richard Critten May 06 '18 at 10:59
-
Watch https://channel9.msdn.com/Events/Build/2014/2-661 from 45:50 – Richard Critten May 06 '18 at 11:03
2 Answers
It depends on the situation.
map
and set
are usually red-black trees, they should do a lot of work to be balanced, or the operation on it will be very slow. And it doesn't support random access. so if you only want to sort one time, you shouldn't use them.
However, if you want to continue insert elements into the container and keep order, map
and set
will take O(logN)
time, while the sorted vector
is O(N)
. The latter is much slower, so if you want frequently insert and delete, you should use map
or set
.

- 1,368
- 5
- 18
-
-
@Nelfeal How big the data is? Well, "the latter is much slower" only means complexity function grows much faster. – con ko May 06 '18 at 11:24
-
True, but that doesn't mean one should use a set by default instead of a vector. And to the question "how big is the data?", the answer usually is "small enough". But of course, as for many other things, it depends. – Nelfeal May 06 '18 at 11:36
-
@Nelfeal Yes, you're right, but I also pointed that only "frequently" operate should use map or set. :) – con ko May 06 '18 at 11:39
The difference between the 2 is noticable!
Using a set, you get O(log(N))
complexity for each element you insert. So by result you get O(N log(N))
, which is the complexity of an insertion sort.
Adding everything in a vector is of complexity O(1)
, and sorting it will be O(N log(N))
since C++11 (before it, std::sort
have O(N log(N))
on average.).
Once sorted, you could use binary_search
to have the same complexity as in a set.
The API of using a vector as set ain't the friendly, although it does give nice performance benefits. This off course is only useful when you can do a bulk insert of data or when the amount of lookups is much larger than the manipulations of the content. Algorithmsable to sort on partially sorted vector, when you have to extend later on. Finally, one has to remark that you don't have the same guarantees of iterator invalidation.
So, why are vectors better? Cache locality! A vector has all data in a single memory block, hence the processor can do prefetching while for a set, the memory is scattered around the place requireing the data to find the next address. This makes vector a better set implementation than std::set for large data when you can live with the limitations.
To give you an idea, on the codebase I'm working on, we have several set and map implementations based on vectors which have their own narratives to function in. (For example: no erase or no operator[])
-
1Honestly, some of that went like a tangent goes past a circle :P But I think the main point is although both gives O(NLogN) complexity on paper vector is better due to more organised data in memory – Indrajit Banerjee May 06 '18 at 13:02
-
1