Python實現(xiàn)計數(shù)排序和基數(shù)排序

桶排序和計數(shù)排序

桶排序

在說計數(shù)排序之前需要先提一下桶排序,因為計數(shù)排序實際上可以被認為是一種特殊的桶排序。
桶排序浸卦,顧名思義该默,需要準備很多桶,比如在一次數(shù)學考試過后地啰,需要給同學們按成績高低排個序愁拭,學生人數(shù)是56,成績最低為0分亏吝,滿分為120岭埠。

我們就可以準備6個桶:A、B、C惜论、D许赃、E、F馆类,每個桶存放不同區(qū)段的成績混聊。
F桶:0~20
E桶:21~40
D桶:41~60
C桶:61~80
B桶:81~100
A桶:101~120

遍歷一遍數(shù)據(jù)將成績放入不同的桶里面之后,再對每個桶里面的數(shù)據(jù)進行快速排序乾巧,然后將排好序的數(shù)據(jù)按FEDCBA的順序合在一起句喜。

桶排序時間復雜度分析

  • 遍歷一次,將數(shù)據(jù)放入對應的桶中卧抗,O(n)
  • 假設數(shù)據(jù)分散比較均勻藤滥,被分到k個桶中,每個桶中數(shù)據(jù)大概是\frac{n}{k}
  • 每個桶內(nèi)的快速排序為O(\frac{n}{k} * log\frac{n}{k})
  • 綜合一下社裆,桶排序的時間復雜度是O(n) + k * O(\frac{n}{k} * log\frac{n}{k})
  • 當k無限趨近與n的時候拙绊,\frac{n}{k}無限等于1,此時桶排序的時間復雜度是O(n)

計數(shù)排序

計數(shù)排序可以認為就是一種特殊的桶排序泳秀,特殊在哪兒呢标沪?計數(shù)排序的桶個數(shù)和要排序的數(shù)據(jù)的范圍一致,比如上面數(shù)據(jù)考試成績排序的問題嗜傅,計數(shù)排序的思想就是根據(jù)范圍0~120來建立121個桶金句,將數(shù)據(jù)分布在121個桶。因為每個桶內(nèi)的數(shù)據(jù)是相等的吕嘀,這樣就不用再進行桶內(nèi)排序了违寞,直接按桶順序合起來就可以了。

計數(shù)排序代碼實現(xiàn)

"""
    計數(shù)排序
    Author: xingrui
"""


# 最大值
def maxNum(nums: list):
    maxNumber = nums[0]
    for number in nums[1:]:
        if maxNumber < number:
            maxNumber = number

    return maxNumber


# 計數(shù)排序
def countSort(nums: list):
    maxNumber = maxNum(nums)

    # 初始化數(shù)組大小
    countArray = [0] * (maxNumber + 1)

    # 將原始數(shù)組的每個元素出現(xiàn)次數(shù)放到countArray中計數(shù)
    for number in nums:
        countArray[number] += 1

    # 累加countArray中的元素偶房,得出在最后結果中的位置關系
    for i, item in enumerate(countArray):
        if i == 0:
            continue
        else:
            countArray[i] += countArray[i - 1]

    result = [0] * len(nums)
    for item in nums[::-1]:
        countArray[item] -= 1
        index = countArray[item]
        result[index] = item

    return result


if __name__ == "__main__":
    nums = [2, 3, 1, 3, 0, 5, 4, 2]
    print(countSort(nums))

基數(shù)排序

基數(shù)排序

基數(shù)排序適用的情景比較特殊趁曼,需要數(shù)據(jù)本身是有層次的,比如對單詞進行排序棕洋,對手機號進行排序挡闰,排序的時候會將每個手機號同一個位置的字符拿出來用計數(shù)排序或者桶排序來排序。

代碼實現(xiàn)

"""
    基數(shù)排序
    Author: xingrui
"""


# 最大值
def maxLength(words: list) -> int:
    length = len(words[0])
    for word in words[1:]:
        if length < len(word):
            length = len(word)

    return length


# 自動補全
def autoComplete(words: list, length: int):
    for i, item in enumerate(words):
        if len(item) < length:
            words[i] = item + "".join(["0"] * (length - len(item)))


# 基數(shù)排序
def radixSort(words: list):
    length = maxLength(words)
    autoComplete(words, length)
    for index in range(length - 1, -1, -1):
        countSort(words, index)

    for i, word in enumerate(words):
        words[i] = str(word).strip("0")


# 計數(shù)排序
def countSort(words: list, index: int):
    # 初始化數(shù)組大小掰盘,ASCII中小寫字母z對應的數(shù)字是122
    countArray = [0] * 123

    # 將原始數(shù)組的每個元素出現(xiàn)次數(shù)放到countArray中計數(shù)
    for word in words:
        letter = word[index]
        countArray[ord(letter)] += 1

    # 累加countArray中的元素摄悯,得出在最后結果中的位置關系
    for i, item in enumerate(countArray):
        if i == 0:
            continue
        else:
            countArray[i] += countArray[i - 1]

    result = [0] * len(words)
    for item in words[::-1]:
        letter = item[index]
        ascii = ord(letter)

        countArray[ascii] -= 1
        result[countArray[ascii]] = item


if __name__ == "__main__":
    words = ["admin", "activity", "birdcage", "heel", "cushion", "fruit",
             "background", "bride", "horse", "zebra", "juice", "bridegroom"]
    radixSort(words)
    print(words)

參考

http://www.reibang.com/p/28ed6963276c
http://www.reibang.com/p/0aff57aa5f8d
http://www.reibang.com/p/be8842b1e5dc

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市愧捕,隨后出現(xiàn)的幾起案子奢驯,更是在濱河造成了極大的恐慌,老刑警劉巖次绘,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叨橱,死亡現(xiàn)場離奇詭異典蜕,居然都是意外死亡断盛,警方通過查閱死者的電腦和手機罗洗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钢猛,“玉大人伙菜,你說我怎么就攤上這事∶酰” “怎么了贩绕?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長壶愤。 經(jīng)常有香客問我淑倾,道長,這世上最難降的妖魔是什么征椒? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任娇哆,我火速辦了婚禮,結果婚禮上勃救,老公的妹妹穿的比我還像新娘碍讨。我一直安慰自己,他們只是感情好蒙秒,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布勃黍。 她就那樣靜靜地躺著,像睡著了一般晕讲。 火紅的嫁衣襯著肌膚如雪覆获。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天瓢省,我揣著相機與錄音弄息,去河邊找鬼。 笑死净捅,一個胖子當著我的面吹牛疑枯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛔六,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼荆永,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了国章?” 一聲冷哼從身側響起具钥,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎液兽,沒想到半個月后骂删,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掌动,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年宁玫,在試婚紗的時候發(fā)現(xiàn)自己被綠了粗恢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡欧瘪,死狀恐怖眷射,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情佛掖,我是刑警寧澤妖碉,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站芥被,受9級特大地震影響欧宜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拴魄,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一冗茸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羹铅,春花似錦蚀狰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至焊切,卻和暖如春扮授,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背专肪。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工刹勃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嚎尤。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓荔仁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親芽死。 傳聞我的和親對象是個殘疾皇子乏梁,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容