Selection of sorting algorithms in STL

Source: Internet
Author: User
Zookeeper

When most programmers need to sort a group of objects, the first algorithm that comes to mind is sort. Sort is a very good algorithm, but it is not perfect in any situation. Sometimes we do not need a full sorting operation. For example, if we have a vector for storing widgets, and we want to send 20 of the best quality widgets to the most important customers, we want to deliver widgets of different quality according to the importance of customers, you only need to sort the first 20 best Widgets. Other widgets do not need to be sorted. In this case, a partial sorting function is required, and an algorithm named partial_sort can perform the following tasks:
Template <class randomaccessiterator>
Inline void partial_sort (randomaccessiterator first, randomaccessiterator middle,
Randomaccessiterator last)
{
_ Partial_sort (first, middle, last, value_type (first ));
}

Template <class randomaccessiterator, class T>
Void _ partial_sort (randomaccessiterator first, randomaccessiterator middle,
Randomaccessiterator last, T *)
{
Make_heap (first, middle );
For (randomaccessiterator I = middle; I <last; ++ I)
If (* I <* First)
_ Pop_heap (first, middle, I, T (* I), distance_type (first ));
Sort_heap (first, middle );
}
The algorithm receives a middle iterator (located within the sequence [first, last), and then reschedules [first, last ),
Sort the Middle-first smallest elements in the sequence in ascending order and place them in [first, middle. The remaining last-middle elements are placed in [Middle, last), and there is no guarantee that there is any specific order. The only reason for choosing partial_sort instead of sort is efficiency. Yes, if you just pick out the first n smallest elements for sorting, of course, the sorting is much faster than the whole sequence.

If you only want to send the best 20 widgets to the most important 20 customers, but do not care which widgets are sent to which customers, partial_sort is not the most appropriate choice, because you only need to find the best 20 widgets, these 20 widgets can be sorted in any order. STL has an algorithm to accomplish such a task:
Template <class randaccessiterator>
Inline void nth_element (randomaccessiterator first, randomaccessiterator nth,
Randomaccessiterator last)
{
_ Nth_element (first, Nth, last, value_type (first ));
}

Template <class randomaccessiterator, class T>
Void _ nth_element (randomaccessiterator first, randomaccessiterator nth,
Randomaccessiterator last, T *)
{
While (last-first> 3)
{
Randomaccessiterator cut = _ unguarded_partition (first, last,
T (_ median (* First, * (first + (last-first)/2), * (last-1 ))));
If (cut <= NTH)
First = cut;
Else
Last = cut;
}
_ Insertion_sort (first, last );
}
This algorithm will rearrange [first, last) so that the elements referred to by nth in the iterator are the same value as the elements at the same position after the [first, last) is fully sorted. In addition, ensure that no element in [nth, last) is smaller than (more accurately, not greater than) in [first, NTH), but for [first, NTH) there is no guarantee for the element order in the subintervals [nth, last) -- this is also a big difference between it and partial_sort.
In addition to finding the top n elements, nth_element has other functions. For example, nth_element can be used to locate the center value of a range or the value on a specific percentage:
Vector <int> ints;
Vector <int>: iterator begin (ints. Begin ());
Vector <int>: iterator end (ints. End ());
Vector <int>: iterator goalposition;
// The following code finds a value with an intermediate level
Goalposition = begin + ints. Size ()/2;
Nth_element (begin, goalposition, end );
// The following code finds the 75%-level element in the interval
Vector <int>: size_type poaloffset = 0.25 * ints. Size ();
Nth_element (begin, begin + goaloffset, end );
Suppose that you don't need 20 widgets with the best quality, but all first-level products and second-level products. Of course, we can sort the entire interval first, and then find the position of an element whose quality value is worse than the second level, the elements between the starting point and the position are exactly what you need. However, full sorting means a lot of comparison and exchange work. It is unnecessary to do so much work for the above tasks. A better strategy is to use the partition algorithm. The partition algorithm can place all elements that meet a specific condition in the front of the interval.
Template <class bidirectionaliterator, class predicate>
Biderectionaliterator partition (bidirectionaliterator first, bidirealialiterator last,
Predicate Pred)
{
While (true)
{
While (true)
{
If (first = last)
Return first;
Else if (PRED (* First ))
++ First;
Else
Break;
}
-- Last;
While (true)
{
If (first = last)
Return first;
Else if (! PRED (* Last ))
-- Last;
Else
Break;
}
Iter_swap (first, last );
++ First;
}
}
Partition will rearrange the elements in the range [first, last. All elements that are determined to be true by the one-dimensional conditional operation Pred are placed in the front of the interval. elements that are determined to be false are placed in the back of the interval. This algorithm does not guarantee that the original relative positions of elements are retained.
Summary:
(1) If you want to perform a full sorting of elements in a vector, String, deque, or array, you can use sort or stable_sort.
(2) If there is a vector, String, deque, or array, and you only need to sort the elements at the beginning of the equivalence, you can use partial_sort.
(3) If there is a vector, String, deque, or array, and you need to find the element at the nth position, or, to find the n elements at the beginning of the equivalence and not sort the n elements, nth_element is the required function.
(4) If you need to distinguish the elements in a standard sequence container from each other based on whether certain conditions are met, partition and stable_partition may be exactly what you need.
(5) if the data is in a list, you can still directly call the partition and stable_partition algorithms. You can use
List: sort to replace sort and stable_sort algorithms. However, if you need to obtain the effect of the partial_sort or nth_element algorithm, you can use the following method to complete this task: (list does not provide a random access iterator, sort, stable_sort, partial_sort, and nth_element require random access to the iterator)
① Copy the elements in the list to a container that provides the random access iterator, and then execute the expected algorithm on the container.
② Create a list: iterator container, execute the corresponding algorithm on the container, and then access the list elements through the iterator.
③ Adjust the elements in the list to the expected target position by repeatedly calling the splice member function using information in an ordered container containing the iterator.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.