📜  C++ STL 中的 sort() vs. partial_sort() vs. nth_element() + sort()

📅  最后修改于: 2021-09-10 03:08:24             🧑  作者: Mango

在本文中,我们将讨论 sort()、partial_sort() 和 nth_element()+sort() 之间的区别。

下面是上述函数的图示:

  1. sort(): C++ STL 提供了一个函数sort()可以在 O(N*log N) 时间内对元素列表进行排序。默认情况下, sort() 按升序对数组进行排序。下面是说明 sort() 的程序:
    // C++ program to illustrate the default behaviour
    // of sort() in STL
    #include 
    using namespace std;
      
    // Driver Code
    int main()
    {
        // Given array of elements
        int arr[] = { 1, 5, 8, 9, 6, 7, 3, 4, 2, 0 };
        int n = sizeof(arr) / sizeof(arr[0]);
      
        // Function sort() to sort the element of
        // the array in increasing order
        sort(arr, arr + n);
      
        // Print the array elements after sorting
        cout << "\nArray after sorting using "
                "default sort is: \n";
        for (int i = 0; i < n; ++i) {
            cout << arr[i] << " ";
        }
      
        return 0;
    }
    
    输出:
    Array after sorting using default sort is : 
    0 1 2 3 4 5 6 7 8 9
    
  2. partial_sort(): std::sort()的变体之一是std::partial_sort() ,它用于排序不是整个范围,而只是它的一个子部分。它重新排列[first, last)范围内的元素,使得中间之前的元素按升序排序,而中间之后的元素没有任何特定顺序。
    下面是说明 partial_sort() 的程序:
    // C++ program to demonstrate the use of
    // partial_sort()
    #include 
    using namespace std;
      
    // Driver Code
    int main()
    {
        // Given array of elements
        vector v = { 1, 3, 1, 10, 3, 3, 7, 7, 8 };
      
        // Using std::partial_sort() to sort
        // first 3 elements
        partial_sort(v.begin(), v.begin() + 3, v.end());
      
        // Displaying the vector after applying
        // partial_sort()
        for (int ip : v) {
            cout << ip << " ";
        }
      
        return 0;
    }
    
    输出:

    1 1 3 10 3 3 7 7 8
    

    partial_sort()的复杂度是O(N*log K) ,其中 N 是数组中元素的数量,K 是中间和开始之间的元素数量。的partial_sort()是除分类更快()如果K大于N作为partial_sort()显著越小排序第一K中的元素,而排序()将所有排序N个元件。
    partial_sort()的最坏情况O(N*log K)运行时间并不能说明全部情况。它在随机输入上的平均运行时间是O(N + K*log K + K*(log K)*(log Nk))
    因为很少有工作可以忽略不属于迄今为止看到的最小K中的每个元素,只是一次比较,所以即使使用渐近更好的算法,常数因子也很难被小K击败。

  3. nth_element(): nth_element()是一种 STL 算法,它以这样一种方式重新排列列表,如果我们对列表进行排序,第 n 个位置的元素就是应该在该位置的元素。
    它不对列表进行排序,只是所有在第 n 个元素之前的元素都不大于它,并且它之后的所有元素都不小于它。
    下面是说明 nth_element() 的程序:
    // C++ program to demonstrate the use
    // of std::nth_element
    #include 
    using namespace std;
      
    // Driver Code
    int main()
    {
        // Given array v[]
        int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 };
      
        // Using nth_element with n as 5
        nth_element(v, v + 4, v + 8);
      
        // Since, n is 5 so 5th element
        // should be sorted
        for (int i = 0; i < 8; i++)
            cout << v[i] << " ";
      
        return 0;
    }
    
    输出:
    3 2 10 23 33 56 45 47
    

下面是三种算法之间的基准比较,将 N 从 0 变化到 10 7 (图中的 X 轴):

nth_element() + sort()解决方案是渐近最快的,并且对较大的K执行更好的结果(大多数人注意到对数刻度)。但是对于K < 70000 的随机输入,它确实输给了partial_sort() ,最多可达6倍。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程