快排雖稱快速排序,但是其嚴格來講
只能稱為是基於比較的排序演算法中相對很優秀的演算法
排序演算法的時間效率下界是o(nlogn)
是僅針對基於比較的排序演算法的
而今天講的o(n)的基數排序演算法
是一種基於內容而不基於比較的排序演算法
下面進入正題,先來嘗試了解基數排序演算法
給出幾個數
239,156,734,237,112,320,255,193
我們嘗試這樣排序,第一步把幾個數分為
[156,112,193] [239,237,255] [320] [734]
即僅按最高位分成幾堆,然後每堆中是保留原順序的
第二步僅按次高位在每堆中繼續調整
[112,156,193] [239,237,255] [320] [734]
最後僅按最低位在每堆中繼續調整
[112,156,193] [237,239,255] [320] [734]
這時排序就完成了
上面這種排序演算法我們稱為最高位優先(most significant digit first)法,簡稱msd法
lsd非常醜的參考**
#include #includeview code#include
#define pb push_back
#define rep(i, j, k) for(int i = j;i <= k;i ++)
using
namespace
std;
int n, a[2000010];
int maxa, maxl, k = 1;
vector
e[2][10];
intmain()
while
(maxa)
rep(i,
2, maxl)
rep(i,
0, 9) for(int j = 0;j < e[maxl & 1][i].size();j ++)
cout
<< e[maxl & 1][i][j] << "";
return0;
}
當然寫這段另外認識到了乙個問題
string和vector中的size()返回值型別均為unsigned int
若size() = 0的話,那麼size() - 1 = 2^32 - 1
另外也因此,輸出中間變數來查錯的時候強烈建議使用cout
我當時查錯用printf("%d\n", size() - 1),輸出當然是-1
然而cout <
基數排序正確性證明略
時間複雜度分析簡單來說即o(maxlen * n)
maxlen為最長數字位數,n為排序元素數字個數
空間複雜度直接o(n + 2n)就可以滿足
直接開o(maxl * n) 是非常浪費空間的
還有可能記憶體**
有的沒的碎碎念:
基於比較的排序演算法效率下界是o(nlogn)
而基於內容的三種排序演算法:桶排序,基數排序,計數排序理論效率均為o(n)級別
而且個人看起來,桶排序和計數排序是沒有什麼營養的
桶排是用某種對映方式將n個元素盡量均勻地分裝在一些有序桶中
然後每個桶分別排序(這裡可以遞迴桶排,可以直接快排)
並且當桶的個數恰好n個時,就變成了計數排序......
然而我們需要注意基於內容的排序演算法的三個特點:
1.對排序的元素有一些要求,比如元素範圍,元素長度等
2.基本都需要採取空間換時間的策略,這種策略有時並不好
3.因為要基於內容,所以對排序元素型別有要求
綜上這些演算法的使用範圍是非常有限的
所以注定了他們是不能像快排一樣眾人皆知的
末尾補充乙個小知識點吧
排序演算法的穩定性是指,原排列中相同的兩個元素
在排序完成後其相對位置是否與原來保持一致
幾個穩定的排序演算法:直接插入排序,氣泡排序,歸併排序,基數排序
當然有些排序演算法的穩定性似乎取決於你對於 < 和 <= 這兩個符號的選擇...
不再繼續討論
基數排序學習
乙個簡單有趣的演算法 基數排序是一種非比較型整數排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。由於整數也可以表達字串 比如名字或日期 和特定格式的浮點數,所以基數排序也不是只能使用於整數。基數排序的方式可以採用 lsd least significant digital ...
基數排序學習
可以拿下力扣164.最大間距。基數排序 英語 radix sort 是一種非比較型整數排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。基數排序是穩定性的排序。步驟 基數排序的時間複雜度是o k n 其中n是排序元素個數,k是數字位數。include include defi...
排序 基數排序
基數排序 radix sort 是屬於 分配式排序 distribution sort 基數排序法又稱 桶子法 bucket sort 或bin sort,顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些 桶 中,藉以達到排序的作用。排序思想 首先按照資料的最低位 個位 將資料分配到0 9...