stl的演算法中,提供了sort()演算法,演算法接收兩個randomaccessiterator。所有關係型容器底層使用紅黑樹的,有自動排序功能。序列容器中的stack,queue使用priority-queue。而優先佇列使用堆實現,它們都有特定的出入口,不允許排序。剩下的vector,list,deque中,list無法使用,因為list的迭代器屬於bidirectioniterators。list是雙向鍊錶。
list的sort()排序**很短,但是不太好懂,這裡從template
void list::sort()
for(int i=0=1;icounter[i].merge(counter[i-1]);
swap(counter[fill-1]);
首先這裡使用到兩個list的函式。void splice(iterator position,list &,iterator i)
函式將i所指的元素結合於position所指的位置之前。
template
void list::merge(list&x )
函式將x合併到*this身上,兩個lists的內容都必須先經過遞增排序。
引數list
的內容會清空,合併過程有排序!!!
下面看一下整個**的具體實現。**開頭先進行了一下校驗。
然後宣告了兩個變數,carry和counter[64]都是拿來作為中間變數進行中轉的。
counter[0]存放2^1次方個元素
counter[1]存放2^2次方個元素
依次類推
怎樣存放呢,原則是當第i個counter[i]中存放的內容個數等於2^(i+1)時,就把counter[i]裡的內容轉移到counter[i+1]
假設我們有個list:7,9,8,6,11。
第一輪:
開始時:
carry:null
fill:0
counter[0]:null
counter[1]:null
1.carry.splice取出第乙個元素
carry=7
2.現在i==fill跳過while迴圈
3.carry.swap之後,carry和counter[0]交換
carry:null
counter[0]:7
counter[1]:null
4.現在執行if(i==fill) ++fill;
fill=1;
結束時:
carry:null
fill:1
counter[0]:7
counter[1]:null
第二輪:1.carry.splice取出第二個元素
carry=9
2.現在icouter[i].merge[carry]
carry:null
counter[0]:7,9
counter[1]:null
注意這裡是的放置已經經過了排序,在merge
裡實現
carry.swap[counter[i++]
carry:7,9
counter[0]:null
counter[1]:null
3.i=1,fill=1退出while迴圈
4.carry.swap之後,carry和counter[1]交換
carry:null
counter[0]:null
counter[1]:7,9
5.現在執行if(i==fill) ++fill;
fill=2;
結束時:
carry:null
fill:2
counter[0]:null
counter[1]:7,9
這樣就把兩個元素歸併到了counter[1]中,下面不再繁瑣的分析取出第三個數字8
,放到counter[0]中,現在counter[0],counter[1]中的數字個數都小於規定數字:
counter[0]:8
counter[1]:7,9
取出第四個數字6
,放到counter[1]中,這是counter[0]中個數定為2
,需要轉移到counter[1]中:
counter[0]:null
counter[1]:6,7,8,9
這時候counter[1]的個數等於4
了,需要把所有的數字轉移到counter[2]中
counter[0]:null
counter[1]:null
counter[2]:6,7,8,9
然後取出11
放到counter[0]中,鍊錶所有元素取完了。結束while迴圈。
把所有結果歸併。
這裡fill
其實表示了乙個
2^(i+1)
次方的判定!!
整個過程總結如下:
將前兩個元素歸併,再將後兩個元素歸併,歸併這兩個小子序列成為4個元素的有序子串行;重複這一過程,得到
8個元素的有序子串行,
16個的,
32個的。。。,直到全部處理完。主要呼叫了
swap
和merge
函式,而這些又依賴於內部實現的
transfer函式(
其時間代價為
o(1))
。該mergesort
演算法時間代價亦為
n*lg(n)
,計算起來比較複雜。
list_sort
中預留了 64個
temp_list
,所以最多可以處理
2^64-1
個元素的序列,這應該足夠了。
spring原始碼分析 spring原始碼分析
1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...
思科VPP原始碼分析(dpo機制原始碼分析)
vpp的dpo機制跟路由緊密結合在一起。路由表查詢 ip4 lookup 的最後結果是乙個load balance t結構。該結構可以看做是乙個hash表,裡面包含了很多dpo,指向為下一步處理動作。每個dpo都是新增路由時的乙個path的結果。dpo標準型別有 dpo drop,dpo ip nu...
redux原始碼分析(三) 原始碼部分
下面是每個部分的一些解讀 createstore apicreatestore reducer,initialstate enhancer 曾經非常好奇這個函式的第二個引數到底是initialstate還是enhancer,因為見過兩種寫法都有的,以為是版本問題。看了原始碼才發現,都可以的。如果你不...