Overview of sorting algorithms in STL [by ACM instructor Guo]

Source: Internet
Author: User
Data Structure Course
I like this article very much. It's Miss Guo's new work! Hope you like it!
The sorting algorithm is described in detail in terms of algorithm efficiency!

There are multiple sorting algorithms in STL, each of which has its own applicability. Let me explain them one by one:

I. Full sorting
Sort ()
First of all, we should introduce sort, which is the most commonly used sort. Sort has two forms. The first form has two iterator parameters to form a forward, open, and closed interval, sort by the less relationship of elements. In the second form, add a predicate for the specified sorting criterion. Sort is basically the most common sorting function. It uses a fast sorting algorithm, and when the number of elements is smaller than a threshold value (usually 16, my experiment is 24) during recursion, convert to insert sort directly. The great mathematician knuth has proved that fast sorting is the fastest on average; of course, the worst complexity is worse. Sort requires a random iterator. Therefore, for many compilers, using sort for forward iterators (such as list) is a compilation error. (However, in vc2005, this error message is really bad)

The basic usage of sort is as follows:

View plaincopy to clipboardprint?
C ++:

# Include
# Include
# Include
# Include

Using namespace STD;

Void func1 ()
{
Vector Ar;
// Insert random numbers into the Array
Generate_n (back_inserter (AR), 100, RAND );
// Sort by size
Sort (AR. Begin (), ar. End ());
}
C ++: # include # Include # Include Using namespace STD; void func1 () {Vector Ar; // insert some random numbers generate_n (back_inserter (AR), 100, RAND) into the array; // sort (AR. begin (), ar. end ());}
There are many ways to implement reverse sorting from large to small, as shown in the following example:
View plaincopy to clipboardprint?
C ++:

Void func2 ()
{
Vector Ar;
// Insert random numbers into the Array
Generate_n (back_inserter (AR), 100, RAND );

// Method 1: Use a function as a predicate
Sort (AR. Begin (), ar. End (), greatethan );
// Method 2: Use the imitation function as the Predicate
// Note that each of the following two methods requires a bracket, which is actually to generate a temporary object
Sort (AR. Begin (), ar. End (), compareint ());
// Method 3: Use the predefined adapter, which is defined in Medium
Sort (AR. Begin (), ar. End (), greater ());
// Method 4: Sort normally and flip it over
Sort (AR. Begin (), ar. End ());
Reverse (AR. Begin (), ar. End ());
// Method 5: Use the inverse iterator
Sort (AR. rbegin (), ar. rend ());
}

C ++: void func2 () {Vector Ar; // insert some random numbers generate_n (back_inserter (AR), 100, RAND) into the array; // Method 1: Use the function as the predicate sort (AR. begin (), ar. end (), greatethan); // Method 2: Use a pseudo function as the predicate. // note that the following two methods must have brackets, in fact, a temporary object sort (AR. begin (), ar. end (), compareint (); // method 3: Use a predefined adapter, defined in Sort (AR. Begin (), ar. End (), greater (); // Method 4: Sort normally, and then flip it over sort (AR. begin (), ar. end (); reverse (AR. begin (), ar. end (); // Method 5: Use the reverse iterator sort (AR. rbegin (), ar. rend ());}
The last method is appreciated by me. You cannot directly use native arrays. That is to say, if Ar is defined as int ar [maxn], the other sorting algorithms above can be simply changed to sort (AR, Ar + maxn ,...), but the last one won't work. Another ugly method should be used:

View plaincopy to clipboardprint?
C ++:

# Include
Void func3 (){
Int ax [5] = {1, 3, 4, 5, 2 };
Sort (reverse_iterator (AX + 5), reverse_iterator (AX + 0 ));
}
C ++: # include Void func3 () {int ax [5] = {1, 3, 4, 5, 2}; sort (reverse_iterator (AX + 5), reverse_iterator (AX + 0 ));}
Stable_sort
Sort has many advantages. One drawback is that it is not a stable sorting. What is the stability of sorting, that is, if two elements are equal, they must be sorted to maintain the original order (for example, we first sort by student ID and then sort by score, in this case, you want to rank the same score in the order of student IDs ). Unfortunately, the fast sorting algorithm is not stable. to pursue this, you have to use stable_sort.

In various sorting algorithms, Merge Sorting is stable, but General Merge Sorting requires additional O (n) storage space, however, this condition is not necessarily met (it may be extravagant ). Therefore, inside stable_sort, first determine whether there is sufficient extra space (for example, cap-size () in vecotr). If yes, use the common Merge function, the total time complexity and fast sorting are an order of magnitude, both of which are O (N * logn ). If there is no extra space, use a key function of merge_without_buffer for local Merge (how to implement it is more skillful, you can talk about it exclusively). This merge process does not require additional storage space, however, the time complexity changes to O (N * logn). In this case, the total time complexity of stable_sort is O (n * logn ).

In short, stable_sort is a little slower, but it can ensure stability. It is used in the same way as sort. However, this method and this function are not used in many cases. For example, in the above example, it is okay to write the score and student ID conditions in the sorting comparison criterion.
View plaincopy to clipboardprint?
C ++:

Class cstudent
{
Public:
Cstudent ();
// Note the const in this comparison function.
Bool operator arstu;
Sort (arstu. Begin (), arstu. End ());
}
C ++: Class cstudent {public: cstudent (); // note the const bool operator arstu; sort (arstu. begin (), arstu. end ());}
Sort_heap
Heap sorting is also a fast Sorting Algorithm with the complexity of O (N * logn ). STL has some heap-related functions that can be used to construct a heap. If the root node is taken out on the constructed heap and placed at the end of the heap, all the elements are cycled, and the final result is ordered. This is sort_heap. Its usage requirements have been constructed in front of the intervals, such:
View plaincopy to clipboardprint?
C ++:

Void func5 ()
{
Vector Ar;
Generate_n (back_inserter (AR), 100, RAND );
Make_heap (AR. Begin (), ar. End ());
Sort_heap (AR. Begin (), ar. End ());
}
C ++: void func5 () {Vector Ar; generate_n (back_inserter (AR), 100, RAND); make_heap (AR. begin (), ar. end (); sort_heap (AR. begin (), ar. end ());}
List. Sort
For list containers, sort (including stable_sort) cannot be used directly. From a technical perspective, sort requires a random iterator. From an algorithm perspective, the list structure is not suitable for quick sorting. Therefore, the list container implements a dedicated sort algorithm, which adopts the Merge Sorting Algorithm and should be stable (uncertain ).

Others
The priority queue (priority_queue) is a max value each time it pops up. It is actually a container packaging of heap.
The associated container itself must be ordered (for the key). During iteration, the key increases progressively.
Ii. Partial sorting
These partial sorting functions can complete the sorting of a piece of data (not all) and save the amount of computing when appropriate. However, there are not many users.

Partial_sort (), partial_sort_copy ()
These two functions can sort the elements of a specified number in the entire interval. That is to say, only the minimum M elements in the result are ordered. You can also use sort. The difference is efficiency. If M is significantly less than N, the time is relatively short; of course M is too small, it is better to find the minimum value one by one.

Partial_sort accepts three parameters, namely, the header, center, and end of the interval. After execution, put the preceding M (M = middle-header) elements in an orderly manner in front of them. The following elements must be larger than the preceding ones, but their internal order is not guaranteed. The difference between partial_sort_copy is that the result is placed in another specified iterator range:
View plaincopy to clipboardprint?
C ++:

Void func6 ()
{
Int ar [12] = {69, 23, 80, 42, 17,15, 26,51, 19,12, 35,8 };
// Only sort the first seven data items
Partial_sort (AR, Ar + 7, Ar + 12 );
// The result is 8 12 15 17 19 26 80 69 51 42 35. The last five data records are not correct.
Vector Res (7 );
// Sort the first seven items and put them into res
Partial_sort_copy (AR, Ar + 7, res. Begin (), res. End (), greater ());
}
C ++: void func6 () {int ar [12] = {69, 23, 80, 42, 17,15, 26,51, 19,12, 35,8 }; // only sort the first seven data parts (AR, Ar + 7, Ar + 12); // The result is 8 12 15 17 19 23 26 80 69 42 42 35, the last five pieces of data are uncertain vectors. Res (7); // put res partial_sort_copy (AR, Ar + 7, res. Begin (), res. End (), greater ());}
The implementation of these two functions uses the heap method. First, the first M elements are constructed into piles, and then the elements are checked one by one to see if they are smaller than the maximum value of the heap, if yes, they will exchange with each other, and then rearrange the heap. Finally, we can perform a sort_heap operation for the heap consisting of the smallest M elements. The algorithm complexity is almost O (N * logm)

Nth_element
This function only sorts the nth element. The function has three iterator inputs (and a predicate can be added, of course). After the execution is complete, the element pointing to the intermediate position must be consistent with the element at the position after full sorting, all elements in the preceding range are smaller than (precisely, they are not greater than) the elements in the following range.

You can immediately find that you are familiar with quick sorting. This is actually a location-based algorithm. The STL specification requires that the average complexity of this function is linear. Like fast sorting, the worst complexity of this algorithm is relatively poor. In general implementation (such as SGI), we use three methods to take 1 for Division elements. The worst complexity is O (n ^ N ). Although there are some algorithms in theory that can ensure the worst linear complexity, the algorithms are too complicated and STL is generally not used.

Iii. Sorting assistance
Partition, stable_partition
Merge, inplace_merge
Iv. Sequential interval operations

Write this article separately.

Reference
Let's continue to look forward to Mr. Guo's help!

Instructor Guo's Boke address: www. skywind. Name/blog

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.