電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 64|回復(fù): 0
收起左側(cè)

std::sort的底層是快速排序嗎?可能遠(yuǎn)不止如此

[復(fù)制鏈接]

475

主題

475

帖子

4237

積分

四級會員

Rank: 4

積分
4237
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-11-27 09:01:00 | 只看該作者 |只看大圖 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
請介紹下C++中的std::sort算法?
回答重點(diǎn)
std::sort 非常高效,它不單純是快速排序,而是使用了一種名為 introspective sort(內(nèi)省排序)的算法。
內(nèi)省排序是快速排序、堆排序和插入排序的結(jié)合體,它結(jié)合這些算法優(yōu)點(diǎn)的同時避免它們的缺點(diǎn),特別是快速排序在最壞情況下的性能下降問題。
注意:本題介紹,僅限于GCC的源碼實(shí)現(xiàn)。
擴(kuò)展知識快速排序:內(nèi)省排序首先使用快速排序算法。利用快速排序分而治之的特點(diǎn),通過選取一個pivot元素,將數(shù)組分為兩個子數(shù)組,一個包含小于pivot的元素,另一個包含大于pivot的元素,然后遞歸地對這兩個子數(shù)組進(jìn)行快速排序。快速排序在平均情況下非常高效,時間復(fù)雜度為 O(n log n)。
  • /// This is a helper function for the sort routine.template typename _RandomAccessIterator, typename _Size, typename _Compare>_GLIBCXX20_CONSTEXPR void__introsort_loop(_RandomAccessIterator __first, _RandomAccessIterator __last,                 _Size __depth_limit, _Compare __comp) {  while (__last - __first > int(_S_threshold)) {    if (__depth_limit == 0) {      std::__partial_sort(__first, __last, __last, __comp);      return;    }    --__depth_limit;    _RandomAccessIterator __cut =        std::__unguarded_partition_pivot(__first, __last, __comp);    std::__introsort_loop(__cut, __last, __depth_limit, __comp);    __last = __cut;  }}
    // sort
    template typename _RandomAccessIterator, typename _Compare>_GLIBCXX20_CONSTEXPR inline void __sort(_RandomAccessIterator __first,                                        _RandomAccessIterator __last,                                        _Compare __comp) {  if (__first != __last) {    std::__introsort_loop(__first, __last, std::__lg(__last - __first) * 2,                          __comp);    std::__final_insertion_sort(__first, __last, __comp);  }}內(nèi)省排序:通過限制快速排序遞歸深度,避免其最壞情況的性能問題。遞歸深度的限制基于輸入數(shù)組的大小,通常是對數(shù)組長度取對數(shù)然后乘以一個常數(shù)(在 GCC 實(shí)現(xiàn)中是 2 * log(len))。如果排序過程中遞歸深度超過了這個限制,算法會切換到堆排序。
  • /// This is a helper function for the sort routine.template typename _RandomAccessIterator, typename _Size, typename _Compare>_GLIBCXX20_CONSTEXPR void__introsort_loop(_RandomAccessIterator __first, _RandomAccessIterator __last,                 _Size __depth_limit, _Compare __comp) {  while (__last - __first > int(_S_threshold)) {    if (__depth_limit == 0) {      std::__partial_sort(__first, __last, __last, __comp);      return;    }    --__depth_limit;    _RandomAccessIterator __cut =        std::__unguarded_partition_pivot(__first, __last, __comp);    std::__introsort_loop(__cut, __last, __depth_limit, __comp);    __last = __cut;  }}
    // sort
    template typename _RandomAccessIterator, typename _Compare>_GLIBCXX20_CONSTEXPR inline void __sort(_RandomAccessIterator __first,                                        _RandomAccessIterator __last,                                        _Compare __comp) {  if (__first != __last) {    std::__introsort_loop(__first, __last, std::__lg(__last - __first) * 2,                          __comp);    std::__final_insertion_sort(__first, __last, __comp);  }}堆排序:當(dāng)快速排序的遞歸深度超過限制時,內(nèi)省排序會切換到堆排序,保證最壞情況下的時間復(fù)雜度為 O(n log n)。堆排序不依賴于數(shù)據(jù)的初始排列,因此它的性能無論在最好、平均和最壞情況下都是穩(wěn)定的。
  • /// This is a helper function for the sort routine.template typename _RandomAccessIterator, typename _Size, typename _Compare>_GLIBCXX20_CONSTEXPR void__introsort_loop(_RandomAccessIterator __first, _RandomAccessIterator __last,                 _Size __depth_limit, _Compare __comp) {  while (__last - __first > int(_S_threshold)) {    if (__depth_limit == 0) {      std::__partial_sort(__first, __last, __last, __comp);      return;    }    --__depth_limit;    _RandomAccessIterator __cut =        std::__unguarded_partition_pivot(__first, __last, __comp);    std::__introsort_loop(__cut, __last, __depth_limit, __comp);    __last = __cut;  }}插入排序:最后,當(dāng)數(shù)組的大小減小到一定程度時,內(nèi)省排序會使用插入排序來處理小數(shù)組。插入排序在小數(shù)組上非常高效,盡管它的平均和最壞情況時間復(fù)雜度為 O(n^2),但在數(shù)據(jù)量小的情況下,這種復(fù)雜度不是問題。此外,插入排序是穩(wěn)定的,可以保持等值元素的相對順序。
  • /// This is a helper function for the sort routine.template typename _RandomAccessIterator, typename _Compare>_GLIBCXX20_CONSTEXPR void __final_insertion_sort(_RandomAccessIterator __first,                                                 _RandomAccessIterator __last,                                                 _Compare __comp) {  if (__last - __first > int(_S_threshold)) {    std::__insertion_sort(__first, __first + int(_S_threshold), __comp);    std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,                                    __comp);  } else    std::__insertion_sort(__first, __last, __comp);}——EOF——你好,我是飛宇。日常分享C/C++、計算機(jī)學(xué)習(xí)經(jīng)驗(yàn)、工作體會,歡迎點(diǎn)擊此處查看我以前的學(xué)習(xí)筆記&經(jīng)驗(yàn)&分享的資源。
    我組建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起進(jìn)群交流。

    歡迎你添加我的微信,我拉你進(jìn)技術(shù)交流群。此外,我也會經(jīng)常在微信上分享一些計算機(jī)學(xué)習(xí)經(jīng)驗(yàn)以及工作體驗(yàn),還有一些內(nèi)推機(jī)會。


    加個微信,打開另一扇窗
    ↓推薦關(guān)注↓
    感謝你的分享,點(diǎn)贊,在看三  

  • 回復(fù)

    使用道具 舉報

    發(fā)表回復(fù)

    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表