List of sorting algorithms in STL

Source: Internet
Author: User
Tags rand sort

STL has a variety of sorting algorithms, each has its own scope of application, below listen to my one by one ways:

I, fully sorted
Sort ()
First of all, it is the most commonly used sort, sort has two forms, the first form has two iterator parameters, forming a front open post-closed interval, sorted by the less relation of the elements; the second form adds a predicate that specifies the ordering criteria. Sort is basically the most general sort function, it uses the fast sort algorithm, and in the recursive process, when the number of elements is less than a threshold (typically 16, my experiment is 24), it turns into a direct insert sort. The great mathematician Knuth has proved that, in the average sense, fast sequencing is the fastest; Of course, the worst complexity is poor. Sort requires a random iterator, so for many compilers, using sort for a forward iterator (such as List) is a compilation error. (However, in vc2005, the error message is really bad)

The basic way to use sort is as follows:

#include <vector>
#include <algorithm>
#include <functional>
#include <cstdlib>

using namespace Std;

void Func1 ()
{
Vector<int> ar;
Insert some random numbers into the array

Generate_n (Back_inserter (AR), N, Rand);
Sort by from small to large

Sort (Ar.begin (), Ar.end ());
}

Often people ask how to sort from big to small, this actually has a lot of implementations in the way, such as the following example:

void Func2 ()
{
    vector<int> ar;
    //inserts some 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 an functor as a predicate

    //Note the following two methods need to have parentheses, in effect, to produce a temporary object

    sort (Ar.begin (), Ar.end (), Compareint ());
    //Method 3: Use predefined adapter, defined in <functional>

    sort ( Ar.begin (), Ar.end (), greater<int> ());
    //Method 4: Normal sort, then flip over

    sort (Ar.begin (), Ar.end ());
    reverse (Ar.begin (), Ar.end ());
    //Method 5: Using the inverse iterator

    sort (Ar.rbegin (), Ar.rend ());
}

The last method is I appreciate, can not directly to the original array, that is, if the definition of AR is an int ar[maxn], the above other sorting algorithm can be easily changed to sort (AR, AR+MAXN, ...) ), but the last one is not, in another ugly way:

#include <iterator>
void Func3 () {
int ax[5]={1,3,4,5,2};
Sort (reverse_iterator<int*> (ax+5), reverse_iterator<int*> (ax+0));
}

Stable_sort
Sort benefits a lot, one drawback is that it's not a stable sort. What is the stability of the order, that is, if there are two elements equal, the order after ordering them to maintain the original sequence (for example, we first sorted by the number of studies, and then ranked by the score, then hope that the same score or in accordance with the order of the school number). Unfortunately, the fast sorting algorithm is not stable, to pursue this, had to use Stable_sort.

in various sorting algorithms, the merge sort is stable, but the general merge sort requires additional O (N) of storage space, which is not necessarily sufficient (perhaps more extravagant). So inside the Stable_sort, first determine if there is enough extra space (such as the Cap-size () part of VECOTR), and some use the normal merge function, the total time complexity and the quick sort of an order of magnitude, all O (N*logn). If there is no additional space, the use of a Merge_without_buffer key function for in-place merging (how to achieve is relatively tricky, can be specifically discussed), the merging process does not require additional storage space, but the time complexity into O (N*logn), in this case, The total stable_sort time complexity is O (N*LOGN*LOGN).

In short, the stable_sort is slightly slower, but can guarantee stability, using the same method as sort. But most of the time you can not use this method and this function, such as the above example, can be in the sorting comparison criteria to write scores and study number two conditions are OK

Class cstudent
{
Public:
    cstudent ();
    //Note the const

    bool operator< (const cstudent) in this comparison function. & RHS) const
    {
        if (m_score! = Rhs.m_score)
            return (M_score < Rhs.m_score);
        return M_name <rhs.m_name;
    }
Protected:
    std::string m_name;
    int M_score;
};
    
void Func4 ()
{
    vector<CStudent> arstu;
    sort (Arstu.begin (), Arstu.end ());
}

Sort_heap
Heap sorting is also a fast sorting algorithm, and the complexity is O (N*LOGN). There are some heap-related functions in the STL that can construct the heap, and if the root node is placed at the tail every time it is taken out on the constructed heap, all elements are cycled over and the final result is ordered. This is the sort_heap. Its use requires that the interval be constructed in front of a heap, such as:

void Func5 ()
{
Vector<int> ar;
Generate_n (Back_inserter (AR), N, Rand);
Make_heap (Ar.begin (), Ar.end ());
Sort_heap (Ar.begin (), Ar.end ());
}

List.sort
For list containers, it is not possible to directly use sort (including Stable_sort), from a technical point of view because sort requires random iterators; From the point of view of the algorithm, the list structure is not suitable for quick sorting. Therefore, a special sort algorithm is implemented inside the list container, which uses the merge sort and should be stable (indeterminate).

Other
The priority queue (priority_queue) pops up with the max value each time. is actually a container-style wrapper for the heap.
The associative container itself must be ordered (for key), and the key is incremented when it iterates over it.


II, partial sorting
These partial sorting functions are able to complete a sequence of data (not all), and in the appropriate fit use can save the computational amount. But there are not many people to use.

Partial_sort (), Partial_sort_copy ()
These two functions can sort a given number of elements in an entire interval, meaning that only the smallest m element in the result is ordered. Of course you can also use sort, the difference is in efficiency. If M is significantly less than N, the time is shorter; Of course m is too small and not good, so it's better to find the minimum value.

Partial_sort accepts three parameters, namely the head, middle, and end of the interval. After execution, the front M (m= Middle-head) elements are placed in an orderly manner before the elements are definitely larger than the previous one, but their internal order is not guaranteed. The difference between partial_sort_copy is that the result is placed in another specified iterator interval:

void Func6 ()
{
int ar[12]={69,23,80,42,17,15,26,51,19,12,35,8};
Sort only the first 7 data

Partial_sort (AR, ar+7, ar+12);
The result is 8 12 15 17 19 23 26 80 69 51 42 35, after 5 data variable

vector<int> Res (7);
First 7 items sorted and placed in Res

Partial_sort_copy (AR, ar+7, Res.begin (), Res.end (), greater<int> ());
}

The implementation of these two functions uses a heap method, first constructs the first m elements in piles, and then checks each of the following elements to see if they are smaller than the maximum value of the heap, and then swaps each other and then rearrange the heap, and finally sort_heap the heap with the smallest m-element in front. The complexity of the algorithm is almost O (N*LOGM)

Nth_element
This function only really sorts out an element, which is nth. The function has an input of three iterators (which can also be added with a predicate, of course), and after execution, the elements in the middle position are guaranteed to be the same as the elements of the position after the full order, and the elements of the preceding interval are less than (precisely, not greater than) the elements of the trailing interval.

Familiarity with quick sorting can be found immediately, which is actually a location-based algorithm. The STL specification requires that the average complexity of this function is linear, and as with fast ordering, the worst complexity of the algorithm is poor. In a general implementation (such as SGI), three kinds of 1 methods are used to find the dividing element, and the worst complexity is O (n^n). Although there are theoretically some algorithms that can guarantee the worst linear complexity, the algorithm is too complex and STL generally does not use it.

III. Sort Assist function
Partition, Stable_partition
Merge, Inplace_merge


IV, ordered interval operation

I'm going to write a separate article.

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.