STL 中的鏈表排序

一直以來學習排序算法, 都沒有在鏈表排序上下太多功夫,因為用得不多。最近看STL源碼,才發現,原來即使是鏈表,也能有時間復雜度為O(nlogn)的算法,

大大出乎我的意料之外,一般就能想到個插入排序。

下面的代碼就是按照源碼寫出的(去掉了模板增加可讀性),注意forward_list是C++11新加的單向鏈表,這里選這個是因為它更接近我們自己實現鏈表時的做法。

void sort_list(forward_list<int>& l){auto it = l.begin();if (l.empty() || ++it == l.end())return;forward_list<int> carry;forward_list<int> counter[64];//總共只設立了64個桶,因為第i個桶被填充的時候,里面至多2^i個元素,2^64,遠超一般元素數目int fill = 0; //fill記錄的是當前填到哪個桶了while (!l.empty()){carry.splice_after(carry.cbefore_begin(), l, l.cbefore_begin());//每次從原鏈表上取下一個元素int i = 0;while (i < fill && !counter[i].empty()){counter[i].merge(carry);carry.swap(counter[i++]);}carry.swap(counter[i]);if (i == fill) ++fill;}for (int i = 1; i < fill; ++i)counter[i].merge(counter[i - 1]);l.swap(counter[fill - 1]);
}

  關于此算法的分析:網上很多爭論這個到底是快速排序還是歸并排序的(侯捷的書上說是快排)。

? ? ? 為了理解這個代碼,可以手動運行一下。

? ? ? fill,記錄用到了幾個桶,最外層循環保證這樣一個事實:從第0個桶到第fill - 1個桶里面,要么為空,要么存儲有2^fill個元素,而且是有序鏈表。

? ? ? 每次與新取下的元素(存儲在carry中)合并的桶都是counter[0]。如果第0個桶里沒有元素,那就直接放進去carry.swap(counter[i])。下一輪循環的

? ? ?時候,因為counter[0]里有元素了,就會進入內層循環,這時候,counter[i].merge(carry)使得第0個桶變為一個含兩個元素的鏈表,然后內層循環第二步,又將這個鏈表

轉移到carry中,下一輪內層循環的時候,帶有兩個元素的carry就會爭取與第1個桶合并(如果第1個桶不空的話),如果第一個桶為空,它將退出內層循環并將元素放進第一個桶,(此時發現i == fill,于是fill變為2)然后下一輪外層循環繼續從鏈表中取下一個元素,(此時counter[0]為空,counter[1]中含有兩個元素),如前面一樣,先是發現counter[0]是空的,進不去內層循環,于是直接把元素填到counter[0]中,下一次外層循環又取一個元素,進入內層循環,與counter[0]合并,交換,然后下一輪內層循環中,帶有兩個元素的carry就會與帶有兩個元素的counter[1]合并,交換, i == fiil == 2退出內層循環,四個元素變到第2個桶中,fill++。

?

?

?

? ? ? ? ? ? ? ? 走完這一遍之后,感覺清晰了,但是除了外層循環的循環不變條件以外,實在是很難從基本的快排或歸并排序的思想中想到這樣去做。

轉載于:https://www.cnblogs.com/hustxujinkang/p/4111510.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257973.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257973.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257973.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

cmd更換編碼類型

chcp 65001 UTF-8 65001 GBK 936 本文出自 “曾頤楠的播客” 博客&#xff0c;請務必保留此出處http://zengyinan.blog.51cto.com/9524976/1721475 轉載于:https://www.cnblogs.com/zengyinanos/p/5042732.html

代碼混淆之后定位線上bug

代碼混淆的目的 代碼混淆的目的是防止競爭對手通過反編譯來閱讀項目代碼。 Android中通過ProGuard來做代碼混淆&#xff08;當然也還有其他的產品可以做代碼混淆&#xff09;。 bug日志反混淆 資料&#xff1a;錯誤log、mapping.txt 異常log&#xff1a; mapping.txt&#xff…

linux怎么切換不同版本的r,在linux中用同一個版本的R 同時安裝 Seurat2 和 Seurat3

在linux中用同一個版本的R 同時安裝 Seurat 2 和 Seurat 3Seurat 作為單細胞分析中的重量級R包&#xff0c;有多好用用&#xff0c;用過的人都知道。Seurat 分析流程基本涵蓋了單細胞分析中的所有常見分析方法&#xff0c;包括filtering&#xff0c;tSNE&#xff0c;UMAP降維及…

Unity手游之路四3d旋轉-四元數,歐拉角和變幻矩陣

http://blog.csdn.net/janeky/article/details/17272625 今天我們來談談關于Unity中的旋轉。主要有三種方式。變換矩陣&#xff0c;四元數和歐拉角。 定義 變換矩陣可以執行任意的3d變換&#xff08;平移&#xff0c;旋轉&#xff0c;縮放&#xff0c;切邊&#xff09;并且透視…

本地通知

本地通知&#xff0c;local notification&#xff0c;用于基于時間行為的通知&#xff0c;比如有關日歷或者todo列表的小應用。另外&#xff0c;應用如果在后臺執行&#xff0c;iOS允許它在受限的時間內運行&#xff0c;它也會發現本地通知有用。比如&#xff0c;一個應用&…

Redux 并不慢,只是你使用姿勢不對 —— 一份優化指南

原文地址&#xff1a;Redux 并不慢&#xff0c;只是你使用姿勢不對 —— 一份優化指南原文作者&#xff1a;Julian Krispel譯文出自&#xff1a;掘金翻譯計劃本文永久鏈接&#xff1a;github.com/xitu/gold-m…譯者&#xff1a;reid3290校對者&#xff1a;sunui&#xff0c;xek…

把windows裝到linux下,如何將WSL(Windows Subsystem for Linux 2)安裝到Windows 10?

原標題&#xff1a;如何將WSL(Windows Subsystem for Linux 2)安裝到Windows 10&#xff1f;Windows 10憑借大受歡迎的WSL(Windows Subsystem for Linux)進入Linux領域。由于最近推出了WSL的最新版WSL2&#xff0c;用戶現在可以利用實際的Linux內核從Windows執行Linux任務。現在…

TWRP-recovery中文界面安裝方法[轉]

把下載到的ui.zip放入sdcard1/twrp文件夾。注意&#xff0c;是內置存儲卡中。如沒有上述文件夾&#xff0c;自行建立后通過文件管理器放入&#xff0c;不是卡刷。文件夾應如下所示&#xff1a;sdcard1&#xff08;內置SD&#xff09; &#xff5c; ┕--twrp&#xff08;文件夾…

如何定期備份網站數據

產生這個問題的背景是我在維護兩個個人的網站&#xff0c;因為采用的是虛擬主機&#xff0c;有時候空間續費不及時等&#xff0c;都可能造成數據的丟失&#xff0c;為了保障數據不丟失&#xff0c;因為有必要每15天左右對網站數據進行備份以防止發生不當的事情。 我們希望做的就…

初創團隊可能不適合應屆生小孩

根據最近招聘中接觸到的一些剛畢業小孩的表現&#xff0c;談談這個問題&#xff1a; 1、扛不住&#xff0c;初創團隊一般最好一人撐一快工作&#xff0c;剛畢業經驗比較薄的小孩在這方面一是心理上不敢擔當&#xff0c;二是能力上確實還需要磨煉成長 2、初創團隊的那個環境可能…

vba執行linux命令,從VBA中的shell命令捕獲輸出值?

慕蓋茨4494581根據Andrew Lessard的回答&#xff0c;這是一個運行命令并將輸出作為字符串返回的函數 -Public Function ShellRun(sCmd As String) As StringRun a shell command, returning the output as a stringDim oShell As ObjectSet oShell CreateObject("WScript…

溢出和剪裁,可見性

內容溢出和剪裁 如果一個元素的內容對于元素大小來說過大&#xff0c;就有可能溢出元素本身。對于此情況&#xff0c;有一些解決辦法可選。 溢出 overflow 值 visible(默認):內容在元素框外可見。一般會導致內容超出其自己的元素框&#xff0c;但不會改變框的形狀scroll:溢出部…

C#= 棧模仿堆的操作

//原理&#xff0c;利用兩個棧&#xff0c;互相作用&#xff0c;來模仿堆的效果&#xff0c;先進先出。。 1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Threading.Tasks;5 6 namespace TwoStacksQueue7 {8 public class Progra…

linux計劃任務執行日志,linux中centos制定計劃任務執行命令并且輸出日志

1.寫腳本最簡單的 寫如下代碼#!/bin/shABC1.每個命令之間用;隔開說明&#xff1a;各命令的執行給果&#xff0c;不會影響其它命令的執行。換句話說&#xff0c;各個命令都會執行&#xff0c;但不保證每個命令都執行成功。2.每個命令之間用&&隔開說明&#xff1a;若前面…

Java-大集合拆分為指定大小的小集合

因為Oracle數據的in 最大允許1000 ,超過就會報錯&#xff0c; 所以需要將集合拆分為多個集合進行處理. /*** 拆分集合* param <T>* param resList 要拆分的集合* param count 每個集合的元素個數* return 返回拆分后的各個集合*/public static <T> List<L…

AsyncTask與多任務

問題由來&#xff1a; 之前看到一篇博文&#xff0c;說AsyncTask不適合運行多任務&#xff0c; 多個任務不會異步執行&#xff0c; 當時只是印象里記住了一下也不確定&#xff0c; 今天把代碼看了看&#xff0c; 把原因寫出來。 問題的代碼演示&#xff1a; 1 public class Asy…

iptables簡單應用

可以修改/etc/rc.d/boot.local讓規則重啟后也能生效&#xff0c;如&#xff1a;/sbin/iptables -F/sbin/iptables -A INPUT -i eth0 -p tcp --sport 80 -j ACCEPT/sbin/iptables -A INPUT -i eth0 -p tcp -j DROP/sbin/iptables -A INPUT -i eth0 -p udp -j DROPiptables是一個…

linux中內部命令有哪些,linux內部命令有哪些

linux中常見的內部命令有&#xff1a;1.exit命令&#xff0c;退出當前的shell&#xff1b;2.history命令&#xff0c;顯示歷史執行過的命令&#xff1b;3.cd命令&#xff0c;切換當前工作目錄&#xff1b;4.source命令&#xff0c;重新執行剛修改的初始化文件&#xff1b;5.ech…

使用SALT-API進入集成開發的簡單樣例

測試的時候&#xff0c;可以CURL -K&#xff0c;但真正作集成的時候&#xff0c;卻是不可以的。 必須&#xff0c;不可以讓TOKEN滿天飛吧。 現在進入這個階段了。寫個樣例先&#xff1a; import salt import salt.auth import salt.log import saltapiopts salt.client.LocalC…

POJ 2778

題意&#xff1a;很Uva項鏈題目類似。 區別&#xff1a; 1、字符串很多&#xff0c;用map hash超時&#xff0c;用Trie查找。 2、DFS判斷連通&#xff0c;和并查集判連通&#xff0c;被我寫錯的地方時&#xff0c;查森林的時候&#xff0c;還是要Find_Set。 1 #include <ios…