📜  C++中的std :: nth_element

📅  最后修改于: 2021-05-30 07:29:47             🧑  作者: Mango

std :: nth_element()是一种STL算法,它以如下方式重新排列列表,即,如果我们对列表进行排序,则位于第n个位置的元素应位于该位置。

它不对列表进行排序,只是第n个元素之前的所有元素均不大于该列表,而后继该元素的所有元素均不小于该列表。
它有两个版本,定义如下:

  1. 使用“”比较元素
    句法:
    template 
    void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                      RandomAccessIterator last);
    
    first: Random-access iterator to the first element in the list.
    last: Random-access iterator to the last element in the list.
    nth: Random-access iterator pointing to the position in the list, 
    which should be sorted.
    If it points to end, then this function will do nothing.
    
    Return Value: Since, return type is void, so it doesnot return any value.
    
    // C++ program to demonstrate the use of std::nth_element
    #include 
    #include 
    using namespace std;
    int main()
    {
        int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 }, i;
      
        // Using std::nth_element with n as 5
        std::nth_element(v, v + 4, v + 8);
      
        // Since, n is 5 so 5th element should be sorted
        for (i = 0; i < 8; ++i) {
            cout << v[i] << " ";
        }
        return 0;
    }
    

    输出:

    3 2 10 23 33 56 45 47 
    

    在这里,第五个元素为33,其左侧的所有元素都小于它,而其右侧的所有元素都大于它。

  2. 通过使用预定义函数进行比较:

    句法:

    template 
    void nth_element (RandomAccessIterator first, RandomAccessIterator nth,
                      RandomAccessIterator last, Compare comp);
    
    Here, first, last and nth arguments are the same as previous case.
    
    comp: Binary function that accepts two elements in the range 
    as arguments, and returns a value convertible to bool.
    The value returned indicates whether the element passed as first argument is 
    considered to go before the second in the specific strict weak ordering it defines.
    The function shall not modify any of its arguments.
    This can either be a function pointer or a function object.
    
    Return Value: Since, its return type is void, so it doesnot return any value.
    
    // C++ program to demonstrate the use of std::nth_element
    #include 
    #include 
    using namespace std;
      
    // Defining the BinaryFunction
    bool comp(int a, int b)
    {
        return (a < b);
    }
    int main()
    {
        int v[] = { 3, 2, 10, 45, 33, 56, 23, 47 }, i;
      
        // Using std::nth_element with n as 6
        std::nth_element(v, v + 5, v + 8, comp);
      
        // Since, n is 6 so 6th element should be the same
        // as the sixth element present if we sort this array
        // Sorted Array
        /* 2 3 10 23 33 45 47 56 */
        for (i = 0; i < 8; ++i) {
            cout << v[i] << " ";
        }
        return 0;
    }
    

    输出:

    33 2 10 23 3 45 47 56 
    

    在此代码中,由于std :: nth_element中第二个参数所指向的第n个元素是数组v的第六个元素,因此这意味着应用std :: nth_element之后数组中的第六个元素应为如果整个数组都排序了,那就是45。

    而且,其左侧的所有元素都小于或等于它,而右侧的元素也大于它。

    二进制函数comp的目的: std :: nth_element以升序对范围[first,last)进行部分排序,以便条件* i <* j(对于版本1)或comp(* i,* j)==范围为[first,nth)的任何i和范围为[nth,last)的j都满足true(对于版本2)。因此,使用comp()来确保nth_element之前的所有元素都小于nth_element之后的元素。

我们在哪里可以应用std :: nth_element()?

  1. 如果我们要查找前n个最小的数字,则可以使用它,但是它们可以排序或可以不排序。
    // C++ program to find first n smallest numbers
    #include 
    #include 
    using namespace std;
    int main()
    {
        int v[] = { 30, 20, 10, 40, 60, 50, 70, 80 }, i;
      
        // Using std::nth_element with n as 3
        std::nth_element(v, v + 2, v + 8);
      
        // Since, n is 3 so now first three numbers will be the
        // three smallest numbers in the whole array
        // Displaying first three smallest number
        for (i = 0; i < 3; ++i) 
        {
            cout << v[i] << " ";
        }
        return 0;
    }
    

    输出:

    20 10 30
    
  2. 就像前n个最小的数字一样,我们也可以通过更改std :: nth_element中作为参数传递的Binary 函数来找到前n个最大的数字
    // C++ program to find first n largest numbers
    #include 
    #include 
    using namespace std;
    int main()
    {
        int v[] = { 30, 20, 50, 60, 70, 10, 80, 40 }, i;
      
        // Using std::nth_element with n as 2
        std::nth_element(v, v + 1, v + 8, std::greater());
      
        // Since, n is 2 so first 2 elements will be the largest
        // among all the array elements
        // Displaying First 2 elements
        for (i = 0; i < 2; ++i) 
        {
            cout << v[i] << " ";
        }
        return 0;
    }
    

    输出:

    80 70
    

    在这里,我们超越了()作为二进制函数,因此如果我们按降序对给定数组进行排序,那么第n个元素将是第n个元素,因此前n个元素将是前n个最大元素。

  3. 它可以用来找到给定元素中位数。
    // C++ program to find the median of the vector
    #include 
    #include 
    #include 
    using namespace std;
    int main()
    {
        vector v = { 3, 2, 10, 45, 33, 56, 23, 47, 60 }, i;
      
        // Using std::nth_element with n as v.size()/2 + 1
        std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());
      
        cout << "The median of the array is " << v[v.size() / 2];
      
        return 0;
    }
    

    输出:

    The median of the array is 33
    

    在这里,排序后的数组将是2 3 10 23 33 45 47 56 60,因此有9个元素,中位数将是中间元素,即第5个元素:33。

std :: nth_element(): O(n)的时间复杂度,其中n是第一个和最后一个之间的距离。
相关文章:

  • std :: search
  • std ::查找
  • std :: find_if,std :: find_if_not
  • std :: find_end
  • std :: sort
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”