C 基數排序另一種實現

2021-07-26 13:40:07 字數 2947 閱讀 9626

這個版本的基數排序和演算法導論的不太相同,思想都是一樣的,但是感覺比那個好理解很多

選用unsigned int 也就是u32 作為例子,按位來,一共只有兩個桶,所以要比32次。但其實基數排序非常有意思。

在於這些都是可變的

設待排序列為n個記錄,d個關鍵碼,關鍵碼的取值範圍為radix,排序時間複雜度為o(d(n+radix)),

空間複雜度2n

這裡n ∈[1e6,1e9) 做了下測試,d=32(因為32bit) ,radix = 2

思路一共兩條,最高位優先msd和最低位優先lsd,都是按位分桶嘛,也就是乙個從頭往尾排,乙個從尾往頭排。兩個都可以,但是msd會有點麻煩,比完高位要是一樣還得再比一下低位,要分出很多子串行。而且並沒有感受到有什麼特別的優點,所以就lsd了

先設乙個tmp陣列,也就是桶。但是因為按位來,0和1可以是乙個大桶裡的兩個小桶

從最低位開始,0放一桶,1放一桶,0從tmp的第0位開始裝,1從最後一位裝。

裝完合併回data,但是注意1那個桶的順序要弄正常一點,之前是倒著裝的。

合併的時候就是0放前1放後,這樣最後是公升序的

程式設計這個之前學排序都是用泛型寫的,基數排序不是很容易泛型。如果不是unsigned , 就要對符號位單獨處理。如果是浮點型別,也可以用基數排序!!!之前被人懟了,當時沒學ieee浮點標準。肯定要對尾數和階碼作特殊處理,我懶得搞了網上有**。

但是這說明乙個道理!如果想相容之前的排序**,就要用模板特化

template

void radixsort(t* data,int left,int right){}

template

<> void radixsort(u32* data,int left, int right)

也就是說,對不同的typename都應該分別實現不同的方法,呼叫的時候會呼叫對應的函式。

時間複雜度與空間複雜度

o(d(n+radix))這個在intro裡面提了一下,可以稍微簡化一下看一下效果,忽略太小的:

o(d*n) 看著是線性的,d一般不會太大,這裡的例子是32,但是快排nlgn的lgn不一定就比d大。這樣分析的話,陣列長度要大於1<<32之後才會看到效果。

但是,基數排序是乙個比較容易並行的排序,並行之後還可以大概除乙個常數(**要寫的非常好才可以把大概去掉)這就可能會比快排好啦。

就是vanilla quick sort 和radix sort比。

#陣列長度1e7

quick sort

1.04497

radix sort

1.65082

#陣列長度1e8

quick sort

11.9672

radix sort

16.6019

#陣列長度1e9

quick sort

133.076

# 爆記憶體啦

為什麼會爆記憶體呢?u32是4byte,1e9個u32也就是4gb!空間複雜度2n剛好我記憶體是8gb。然後就只能重啟了= =

這樣的話是不如快排快的,改進思路就是換基數和cuda並行

template

void radixsort(t* data,int left,int right){}

template

<> void radixsort(u32* data,int left, int right)

for(u32 i = 0;i < cnt0;i++)

data[i] = tmp[len - i -1];

for(u32 i = 0;cnt0 < len;i++)

data[cnt0++] = tmp[i];

}delete tmp;

}

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

using u32 = unsigned

int;

using type = u32;

const

int len =(int)1e6;

template

void disp(t* data,int l)

cout

void init(t* data,int len)

template

void qsort(t* data,int left = 0,int right = len-1)

}bool sorted = false;

template

void sortswap(t* data,int index,int right)

}template

void oddevensort(t* data,int left = 0,int right = len-1)

}template

void radixsort(t* data,int left,int right){}

template

<> void radixsort(u32* data,int left, int right)

for(u32 i = 0;i < cnt0;i++)

data[i] = tmp[len - i -1];

for(u32 i = 0;cnt0 < len;i++)

data[cnt0++] = tmp[i];

}delete tmp;

}template

void (*f)(t*,int,int) =

;int main()

delete data;

return

0;}

另一種table排序

click on the table header to sort in ascending order.last name first name birthday siblings smith john 7 12 1978 2johnson betty 10 15 1977 4henderson ...

另一種尊重

上中學的時候,有一節課印象非常深刻。老師問我們如果無意闖入乙個房間,發現房間裡有一位女士正在洗澡,這時應該怎麼辦?有同學回答就當什麼也沒看見,退出房間。還有同學回答 說聲對不起!女士。然後退出去。老師笑了笑說,還有更好的答案,那就是 對不起,先生!有一對結婚多年的夫妻,有一次出差在外的妻子有一件急事...

另一種勝利

另一種勝利 written by allen lee 剛才我的扣殺,出界了5.3厘公尺。雖然很可惜,但還是出界了,請確認下吧。幹 真是的,那些任性的傢伙!但是,到最後還只顧自己網球原則的正直笨蛋,和一定要用迴旋蛇標打中單人區的笨蛋,給我們看了場好比賽啊。龍崎 海棠和幹他們雖然輸了這場比賽,但他們堅持...