list sort原始碼分析

2021-07-05 22:34:12 字數 4601 閱讀 8418

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,因為見過兩種寫法都有的,以為是版本問題。看了原始碼才發現,都可以的。如果你不...