1. 程式人生 > >演算法學習——基數排序

演算法學習——基數排序

基數排序是一種複雜度為n * max(每個數的位數)的優秀演算法,平常用的不多,但求字尾陣列的時候為了達到nlogn的複雜度一般都會採用基數排序,因此還是很有必要學一下的。

大概的意思就是說,對於一個數列而言,我們先以個位數為權值桶排一遍得到一個新的排列,然後再在這個排列的基礎上以十位數為權值桶排一遍得到一個新的排列,再在這個排列的基礎上以百位數為權值桶排一遍得到一個新的排列……最後以所有數中的最大位數為權值桶排一遍得到一個新的序列,這個最後得到的新序列就是已經拍好序的了。

舉個例子:

  我們現在有12 23 39 15四個數,我們先以個位數為權值桶排一遍 ,得到新序列12 23 15 39.

  然後再以十位數為權值桶排一遍,這個時候會發現1號桶中出現了2個數,分別是12和15,然後觀察到在第一次排序得到的序列中,12在前面,因此我們給12的排名定為1,15的排名定為2.

  於是我們就得到了最後的序列12 15 24 39.

因為後面的排序雖然會打亂上一次的排序結果,但打亂它的原因是有些數的當前位不相同。又因為對於任意一個數而言,它的當前位大,那麼不管它之前的位有多小,它都比別人大。

例如:9000 > 1999,因為9000的千位比1999大,所以即使它的個、十、百位都比1999小,它仍然比1999大。

 

對於當前位相同的數,我們是不會改變它們的相對位置的,例如上一次排序的結果(區域性)是123,146,157,那麼因為它們的當前位(百位)都為1,我們不會改變這幾個數的排列,所以就保證了整體的有序。

 

如果仍有疑問,不妨看看這個例子:

  假如我們上一次得到的排序結果是: 12 23 14 37 18.

  那麼正確的序列顯然是12 14 18 23 37.

  那麼我們怎麼在已經根據個位排好序的情況下再根據十位排出正確的序列呢?

  首先因為是桶排,1號桶中會存放14 12 18這幾個數,2號桶中會存23,3號桶中存37.

  然後我們依次從1,2,3號桶中取數。

  1號桶中有3個元素,我們按照上一次排序的順序依次取出得到12 14 18,對於後面的桶都只有一個元素,直接取出即可。

  於是我們就得到了12 14 18 23 37這個序列