Understand your sorting operations (stable_sort, sort, partial_sort, nth_element, stable_partition, partition)

Source: Internet
Author: User

Sorting is always common in data structures.AlgorithmSTL provides a wide range of sorting algorithms. It is worth exploring how to use them effectively. I did not find the translation for Clause 31 on the Internet, so I translated it myself. -- Winter

How to sort data? There are several ways to count.

OnceProgramTo sort container elements, the sort algorithm will appear in his mind immediately (some programmers may think of qsort, but after reading the clause 46 in detail, they will give up the idea of using qsort and use sort algorithm ).

Sort is a very good algorithm, but when you don't really need it, it is actually a waste. Sometimes you do not need a complete sorting (full sorting for short ). For example
A vector container containing a widget object (the widget is a "small pendant"). What you need to do if you want to send 20 widgets with the best quality to your best customers
Just find out the 20 most quality widgets, And the rest do not need to care about their order. In this case, you need partial sorting (relative to full sorting), which is a real part of the algorithm.
Sort by function: partial_sort:

Bool qualitycompare (const widget & LHS, const widget & RHs)
{
// Returns true if the quality of LHS is no worse than that of RHS. Otherwise, false is returned.
}
...
Partial_sort (Widgets. Begin (), // put the best quality of 20 Elements
Widgets. Begin () + 20, // put it in the widgets container in sequence
Widgets. End (),
Qualitycompare );
... // Use widgets...

By calling partial_sort, the first 20 elements in the container are the 20 widgets with the best quality you need, which are arranged in order.
Widgets [0],
Followed by widgets [1], and so on. In this way, you can send the quality first widget to your best customer, and the quality second widget to the next customer.
That's more convenient.

If you just want to give the 20 best quality widgets to your 20 best customers, and do not need to give them one-to-one correspondence, partial_sort is somewhat larger here
Small materials are used. Here, you only need to find these 20 elements, instead of sorting them themselves. What you need is not partial_sort,
Nth_element.

the nth_element sorting algorithm only sorts a range until the correct element is placed at the nth position you specified. That is, compared with
nth_element sorting, the nth position is the same element. After the nth_element function is run, the elements after position N should not appear in the full sorting.
before N, the element before position n does not appear behind n. It sounds a bit confusing, mainly because I have to use my language carefully to describe the nth_element function. Don't worry
I'll explain why later. Now let's take a look at how nth_element puts the best 20 widget gifts at the top of the vector container:

Nth_element (Widgets. Begin (), // put the best quality 20 elements in
Widgets. Begin () + 20, // front of the widgets container,
Widgets. End (), // but do not care about these 20 Elements
Qualitycompare); // Internal Order

As you can see, calling the nth_element function is essentially the same as calling the partial_sort function. The only difference is that partial_sort
The 20 elements are also arranged, and nth_element is not related to their internal order. Both algorithms implement the same function: Put the best 20 elements in the vector container
Start part.

This raises an important question: what will the Sorting Algorithm do if the quality is the same? Assume that the quality of 12 elements is 1 (the best level), and the quality grade of 15 elements is
2 (quality times), if you want to select 20 best widgets, first select 12 quality 1 elements, and then select 8 quality 2 elements from 15. Nth_element
And partial_sort How to Select 8 from 15, what is the basis? In other words, when multiple elements have the same comparison value, how does the Sorting Algorithm decide who is first and then who?

For partial_sort and nth_element algorithms, you cannot control them. For elements with the same comparison value, you can arrange them as you want (see article 19.
). In our above example, we need to select 8 elements with 15 levels of 2 and add them to the top
20. This also makes sense: If you want to get 20 widgets with the best quality, and some widgets have the same quality, when you get 20 elements
There is no less quality than the remaining ones. If this meets your requirements, you cannot complain.

For full sorting, you can gain more control. Some sorting algorithms are "stable". In a "stable" Sorting Algorithm, if the two elements have the same value,
Their relative positions remain unchanged after sorting. For example, if widget a is in the widget
Before B, and all have the same quality level, then the "stable" sorting algorithm can ensure that after sorting, widget A is still in the widget
Before B. This is not guaranteed by the "stable" sorting algorithm.

Neither partial_sort nor nth_element is a "stable" sorting algorithm. The true "stable" Sorting Algorithm is stable_sort, which is known by name.
It is "stable. If you need to ensure the relative position of the same element during sorting, you 'd better use stable_sort. in STL, it is not for partial_sort and
The nth_element algorithm provides the corresponding "stable" version.

When it comes to nth_element, the name is really strange, but there are many functions. In addition to allowing you to find Top N irrelevant elements, it can also find the value of a range, or find the value at a specific percentage point.

vector :: iterator begin (widgets. begin (); // The first
vector : iterator end (widgets. end (); // and the last iterator
//
vector : iterator goalposition; // The iterator to be located

// The following Code The iterator used to obtain the element with the quality in the middle.
Goalposition = begin + Widgets. Size ()/2; // The element to be searched should
// In the middle of the vector.
Nth_element (begin, goalposition, end, // locate the value of the widgets element in the container
Qualitycompare );//
... // Goalposition now points to the median Element

// The following code is used to obtain the 75% quality element.
Vector <widget>: size_type goaloffset = // calculate the value to be found.
0.25 * Widgets. Size (); // The distance from the in iterator.
//
Nth_element (begin, begin + goaloffset, end, // gets the element with the quality ranking at 75%.
Qualitycompare );//

... // Goalposition now points to the element with quality ranking at 75%.

When you need to change a set from unordered to ordered, you can choose sort, stable_sort or partial_sort.
N or an element at a specific position, you can use nth_element. Sometimes you have fewer requirements than nth_element provides. For example, you do not need to get the best quality.
For the first 20 widgets, you only need to identify the widgets whose quality level is 1 or 2. Of course, you can complete the whole vector according to the widget quality level.
Sort and find the first element whose quality level is lower than level 2.

The problem is that full sorting is too resource-consuming, and most of the work is useless. In this case, it is best to select the partition algorithm. The partition is just for you to determine a range
Elements that meet specific conditions are placed in this interval. For example, to put the elements of widgets whose quality level is better than or equal to Level 2 at the front end of the widget container, we can define
Widget quality level function:

Bool hasacceptablequality (const widget & W)
{
// If W quality is equal to or greater than 2, true is returned; otherwise, false is returned.
}

Then pass the judgment function to the partion algorithm:
Vector <widget>: iterator goodend = // set all
Partition (Widgets. Begin (), // place the condition in front of the widgets container,
Widgets. End (), // returns the first condition that does not meet the condition
Hasacceptablequality); // The Position of the element

In this way, all elements between the iterator Widgets. Begin () and the iterator goodend are the elements that meet the requirement: the quality level is better than or equal to 2. In
Goodend to Widgets. End ()
The quality level of each element is lower than the quality level 2. If you are concerned about the relative position of the same quality level element, you can use the stable_partition algorithm instead.
Partition.

Note that the sort, stable_sort, partial_sort, and nth_element algorithms both need to use the random iterator (Random Access
Iterators), so these algorithms can only be used for vector, String, deque,
For containers such as arrays, these algorithms are necessary for standard associated containers such as map, set, multmap, and multset. The comparison functions of these containers make
Elements are always arranged in an orderly manner. For the container list, it seems that these sorting algorithms can be used, but they are also unavailable (the iterator type is not a random iterator), but when needed
You can use the sort function sort that comes with the list function (interestingly, the list: sort function works the same as a "stable" sort function ). If you want to use
Partial_sort or nth_element, which can only be used indirectly. An optional method is to copy the elements in the list to a container with a random iterator, and then use these
The other is to generate a container containing list: iterator, sort the list: iterator in the container directly, and then
List: iterator to get the specified element. The third method is to use an ordered container containing iterator and repeatedly connect the elements in the list to the bit you want to link.
. As you can see, there are still many options.

Partition
The stable_partition and stable_sort functions are different from sort, stable_sort, partial_sort, and nth_element functions. The requirements are not so strict.
If the input parameter is bidirectional
Iterator ). Therefore, you can use the partition and stable_partition algorithms for all standard sequence containers.

Let's summarize your sorting operations:

To sort the vector, String, deque, or array containers in full order, you can select sort or stable_sort;

If you only need to obtain the top n elements in the vector, String, deque, or array container, partial_sort is the first choice.

For a vector, String, deque, or array container, you need to find the element at the nth position or you need to get the top N and it is not related to the internal order in Top N, nth_element is the most ideal;

If you want to separate elements that meet or do not meet a certain condition from the standard sequence container or array, you 'd better use partition or stable_partition;

If you use the list container, you can directly use the partition and stable_partition algorithms. You can use list: Sort instead of sort and
Stable_sort sorting. If you want to obtain the sorting effect of partial_sort or nth_element, you must use it indirectly. As described above, there are several methods available.
Select.

In addition, you can use standard associated containers to ensure that all elements in the container are always in order during operations. You can also consider the non-standard STL container priority_queue, which can also
To ensure that its elements are always ordered during all operations (priority_queue is a part of STL in the traditional sense, but according to the definition of "STL", STL containers need to support Iteration
Priority_queue does not support the iterator, so it cannot be called a standard STL container ).

Then you may ask, "What is the performance ?" Very good question. Broadly speaking, the more work the algorithm does, the longer the time it takes. The "stable" sorting algorithm takes longer than the "unstable" sorting algorithm. We can sort the sort algorithms discussed in this article based on the amount of resources consumed (Time and Space). The fewer resources consumed, the higher the ranking:

1. Partition

2. stable_partition

3. nth_element

4. partial_sort

5. Sort

6. stable_sort

These algorithms are chosen based on your needs rather than their performance. If you can select an algorithm that meets your needs (for example, partial sorting instead of full sorting), it will not only clearly express your intention, but also efficiently use STL.

Here is a small example:

# Include <iostream>
# Include <vector>
# Include <iterator>
# Include <cstdlib>
# Include <algorithm>
# Include <functional>

Using namespace STD;

Bool less5 (int)
{
Return a <5;
}

Int main ()
{
Const size_t n = 10;
Int A [10] = };
Vector <int> IVE (A, A + n );
Cout <"after sort; \ n ";
Sort (A, A + n );
For (INT I = 0; I <n; ++ I) cout <A [I] <"";
Cout <Endl;

Cout <"the top 4 Number:" <Endl;
Partial_sort (IVE. Begin (), Ive. Begin () + 4, Ive. End (), greater <int> ());
Copy (IVE. Begin (), Ive. Begin () + 4, ostream_iterator <int> (cout ,""));

Cout <"\ nthe 4th number:" <Endl;
Nth_element (IVE. begin (), ive. begin () + 3, ive. end (), greater <int> (); // note that it is ive. begin () + 3
Cout <Ive [3];

Cout <"\ nthe Top 4 Number:" <Endl;
Copy (IVE. Begin (), Ive. Begin () + 4, ostream_iterator <int> (cout ,""));

Cout <"\ nthe numbers are divided less or greater 5:" <Endl;
Partition (IVE. Begin (), Ive. End (), less5 );
Copy (IVE. Begin (), Ive. End (), ostream_iterator <int> (cout ,""));
Cout <Endl;

System ("pause ");
Return 0;
}

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.