questions about the searching and sorting algorithms

Viewed 201

I'm doing a little research about searching and sorting algorithms in the Standard library. I couldn't find something about those questions. I hope someone can help me out. You can also send me links if you know some.

  • Does the searching behavior change if the data is not sorted compared to one which is sorted?

  • How can I know if it is better to use std::sort() on a vector instead of maybe to copy the vector to an already sorted set? That is just an example. I hoped to find some explanations on the web which ways are the best for searching or sorting, but I didn't.

  • How can I adapt the behavior of the searching and sorting algorithms to make it more efficient?

2 Answers

Does the searching behavior change if the data is not sorted compared to one which is sorted?

No. It depends on the algorithm you choose. General search std::find is O(n), binary search std::lower_bound is O(log n), but it works only on sorted ranges.

How can I know if it is better to use std::sort() on a vector instead of maybe to copy the vector to an already sorted set? That is just an example. I hoped to find some explanations on the web which ways are the best for searching or sorting, but I didn't.

You can write a benchmark and measure. You can sort an std::vector (without duplicated elements) by copying it into an std::set, which maintains sorted order internally. std::set is typically implemented as a red-black tree and has in general high memory fragmentation in contrast to contiguous std::vector. So it is easy to predict the result. Alexander Stepanov discusses (if I remember correctly) this particular example in his lectures available on YouTube.

Does the searching behavior change if the data is not sorted compared to one which is sorted?

Depends. If you access your data in a vector/array by position, there's no performance improvement, and there's no need for sorting neither.

Searching can be done linearly, binary, keys, and by hash function.

For small (I guess something below a few dozens of items) and contiguous containers (e.g. a vector) linear search can be the fastest, just because of cache-friendly memory layout.

Binary search has O(log N) complexity which is likely the best you can get... I'm thinking in Information theory. It requires that you sort previously the container. It's useful for frequetly searches in the same container.

A std::set (and its cousin std::map) uses internally a tree, which makes searching O(log N) complexity too. Useful if you search by keys, instead of some criteria of your items. The drawback is that it's a bit slower on building (always keep sorted) than fill a vector an later sort it.

A hashmap or hashtable uses a function for getting the bucket where the item lies. The complexity is something near to O(1), depending on number of items and the function used (collisions issue).

As you see, selecting a type of container depends on how are you going to handle your data. Choose the one that fits your requirements.

How can I know if it is better to use std::sort() on a vector instead of maybe to copy the vector to an already sorted set?

std::sort changes the container so the result is, obviously, sorted. If you need the original, unordered, container, then make a copy and sort the copy. Sorting the whole of the container is better that "insert-item-so-container-is-always-sorted" for all items, specially with a vector (many memory reallocations); a set/map filling process may be not that slow.

How can I adapt the behavior of the searching and sorting algorithms to make it more efficient?

It's not clear to me what you mean. But, "The end justifies the means". Again, choose the container that servers best for your data handling.

Related