20191209 八大排序之基數排序

2022-07-20 08:39:13 字數 3478 閱讀 5020

基數排序(radix sort)是一種只適用於數字或字母型別的排序方法,它檢查數字或字母的每一位,將之分類,按照位數的特定順序,來將元素排列。以數字為例,將所有元素按照個位數字分類,分類好後,將個位數字大小排列組合起來,再按照十位數字分類,再按照數字大小排列組合起來,一直到最大數字為止。

基數排序的方式分為2類:

lsd(least significant digital):lsd的排序方式由鍵值的最右邊開始,先比較最低位,也就是個位,進行分桶,分桶過程中分到乙個桶中的資料直接追加到桶中即可,無需排序。然後將所有同種的元素按桶的順序拿出,重新組成序列,然後比較十位,進行分桶…直到比較到最高位,重新組成序列即可完成排序。

msd(most significant digital):由鍵值的最左邊開始,先比較最高位,最高位分到乙個桶中的,再按照第二位進行分桶…,知道分到最後一位,然後再從最小的桶中逐層向上,把元素都拿出來,即完成排序。

首先確定待排序陣列中值的最大位數,用於確定程式中要作幾輪排序;

定義乙個集合陣列,陣列大小十,對應角標範圍0-9,用來儲存每輪排序過程中對應的位數上的值;

每輪排序依次從原始陣列中取值,並判斷對應位數上的值,不足位數時在前面補上相應的0,然後放到對應角標的桶內;

每輪排序後,按角標大小依次取出不為空的桶內的值,合併成為乙個部分排序後的新陣列;

將上述部分排序後的新陣列作為下一輪高一位位數上的值排序的原始陣列,重複上述排序的步驟,直到生成最終排好序的陣列。

lsd具體邏輯如下:

msd具體邏輯如下:

從最高位數上的值開始排序,一輪排序結束後,並沒有急著合併整理,而是判斷每個桶內的元素,如果桶內的元素大於1個則繼續對當前桶進行排序,直到排到最低位數上的值,最終做一次性合併整理,形成排序後的陣列。

def

bucketsort(arr):

max_num =max(arr)

i =0

#(max_num//10**i)%10>0表示當陣列中最大的數的最高位沒有進行排序前,都一直迴圈

while (max_num//10**i)%10>0:

buckets = [ for i in range(10)]

for num in

arr:

#(num//10**i)%10獲取當前排序的基準數(對應的桶號),如取320的第二個數,則需要放置在2號桶中

arr =

#將桶中的陣列從新組合為乙個新的陣列

for bucket in

buckets:

arr+=bucket

i +=1

return arr

def

bucketsortmsd(arr,max_length):

if max_length<=0:

return

arr

print("

對於當前陣列%s按照右起第%s位數排序

"%(arr,max_length))

buckets = [ for i in range(10)]

for num in

arr:

#num // 10 ** (max_length - 1) % 10 ** (max_length) 獲取當前數字的桶index

bucket_idx = num//10**(max_length-1)%10**(max_length)

arr =

for bucket in

buckets:

if len(bucket)>2:

arr+=bucketsortmsd(bucket,max_length-1)

else

: arr+=bucket

return arr

def

bucketsortletterlsd(arr):

sort_arround =len(max(arr))

while sort_arround>=0:

buckets = [ for i in range(26)]

for letter in

arr:

if sort_arround>=len(letter):

bucket_index =0

else

: arr =

for bucket in

buckets:

arr+=bucket

sort_arround-=1

return

arrarr = ["

banana

","","

orange

","ape

","he"]

print(bucketsortletterlsd(arr))

根據計算出的桶的索引放置單詞,並且放置後按照桶的位置從0-26逐一取出桶中的單詞放回序列,然後進行下一輪排序,一直到排序完最後一輪。

1. 不管待排列表是多少個元素,以及元素的長度為多少,都需要建立27個桶,分別對應其他字元以及a-z的26個英文本母

2. 獲取待排元素的的最長的單詞作為排序的輪數

3. 從低位到高位依次排序(注意:一定是要從地位到高位才能完成我們的字典序)

具體**分為2個函式,乙個函式是獲取字母應該放置到哪個桶中,乙個函式根據獲取的桶的索引將元素放置入桶中

def

letterbucketsortmsd(arr,sort_idx):

"""sort_idx表示按照給定arr中陣列中字母的第幾個索引進行排序

"""#

如果排序的字母位索引超出最大長度,直接返回陣列,如對字母abc按照下標3第4個字母進行排序,這種情況無需排序,直接返回

if sort_idx>len(max(arr)):

return

arr

#建立26個桶

buckets = [ for i in range(26)]

for letter in

arr:

if len(letter)>sort_idx:

#獲取桶的索引

bucket_index = ord(letter[sort_idx])-97

else

: bucket_index =0

arr =

for bucket in

buckets:

#如果桶中的元素超過2個,則繼續排序,最後合併桶

if len(bucket)>=2:

arr+=letterbucketsortmsd(bucket,sort_idx-1)

else

: arr+=bucket

return arr

lsd從低位開始排到高位,每排一位都是把各個桶合併,再按下一位排序;

msd從高位開始排到低位,排完一位後不合併桶,相同的高位劃分子桶繼續分配,最後再合併。

堆排序本身沒有普適性,僅能用於特定的陣列排序,如字母和數字的排序。

20191209 八大排序之氣泡排序

在陣列arr n 中,從第乙個數開始,拿arr i 和後面的數arr i 1 進行比較,如果arr i 比後面的大,就交換兩個數的位置,這樣遍歷一遍陣列後,把最大的資料排在了最後面,之後繼續迴圈排剩下的n 1個數,直到完成所有的排序,由於每次都是把最大的排到最後面,就好像冒泡一樣,故取名氣泡排序,具...

20191209 八大排序之選擇排序

選擇排序的演算法核心思想是從陣列中選擇最小的元素,放到第乙個位置,再從陣列中選擇第二小的元素放到第二個位置,一直到陣列的最後乙個元素為止。具體邏輯如下 選擇陣列的第一小的元素,將其放在第乙個位置 選擇陣列的第二小的元素,將其放在第二個位置 選擇陣列的第三小的元素,將其放在第n個位置 def sele...

八大排序之基數排序

個人部落格 建議先看排序綜述,傳送門 資料結構與演算法系列之一 八大排序綜述。基數排序 英語 radix sort 是一種非比較型整數排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。由於整數也可以表達字串 比如名字或日期 和特定格式的浮點數,所以基數排序也不是只能使用於整數...