C++ partial_sort(部分排序)

zrpstc發表於2020-10-05

參考:http://c.biancheng.net/view/564.html

定義

假設有一個容器,它儲存了 100 萬個數值,但我們只對其中最小的 100 個感興趣。可以對容器的全部內容排序,然後選擇前 100 個元素,但這可能有點消耗時間。這時候需要使用部分排序,只需要這些數中的前100個是有序放置的。

對於部分排序,有一個特殊的演算法 partial_sort(),它需要 3 個隨機訪問迭代器作為引數。如果這個函式的引數是 first、second 和 last,那麼這個演算法會被應用到 [first,last) 這個範圍內的元素上。執行這個演算法後,[first,second) 會包含降序序列 [first,last) 中最小的 second-first 個元素。

[first,last),用它來表示一個元素段,這是一個來自於數學領域的用來定義數字範圍的概念——區間。這兩個值叫作結束點,在這種表示法中,方括號表示包含相鄰的結束點,圓括號表示相鄰的結束點不包括在內。 例如,如果 (2,5) 是一個整數區間,2 和 5 都被排除在外,所以它只表示整數 3 和 4;這也被叫作開區間,因為兩個結束點都不包含。區間 [2,5) 包含 2 但不包含 5,所以它表示 2、3 和 4。(2,5] 表示 3、4 和 5。[2,5] 表示 2、3、4、5,並且它被叫作閉區間,因為包含了兩個結 束點。當然,first 和 last 都是迭代器,並且 [first,last) 表示包含 first 指向的元素而不包含 last 指向的元素,所以可以用它準確表示 C++ 中的範圍。

排序演算法

size_t count {5}; // Number of elements to be sorted
std::vector<int> numbers {22, 7, 93, 45, 19, 56, 88, 12, 8, 7, 15, 10};
std::partial_sort(std::begin(numbers), std::begin(numbers) + count, std::end(numbers));
  • 排序過程:

在這裡插入圖片描述
最小的 count 個元素是有序的。在 [first,second) 範圍內,second 指向的元素沒有被包含在內,因為 second 是一個開結束點。圖 1 展示的是在本人系統上這段程式碼執行後的結果。在你的系統上結果可能會不同。需要注意的是,不能保持未排序元素的原始順序。在執行 partial_sort() 後這些元素的順序是不確定的,這取決於我們的實現。

  • 過載運算子

如果想讓 partial_sort() 演算法使用和 < 運算子不同的比較函式,可以提供一個函式物件作為它的額外引數。例如:

std::partial_sort(std::begin(numbers), std::begin(numbers) + count, std:: end (numbers) , std::greater<>());

輸出結果:

93 88 56 45 22 7 19 12 8 7 15 10

  • 例項:對於n個數字求最大的m個元素
partial_sort(a, a + m, a + n, greater<int>());

相關文章