python實(shí)現(xiàn)幾種常見的排序算法

以下排序算法均按照從小到大排序N個元素:

1、冒泡排序

基本思想:
遍歷元素列表,比較相鄰的元素专挪,如果第一個比第二個大,則交換其位置茄猫,經(jīng)過第一輪比較狈蚤,最大的元素將恰好被放置到最后一個;
第二輪不再比較最后的元素划纽,只比較前面的N-1個元素脆侮,則經(jīng)過第二輪比較之后,我們可以確定第二大的元素勇劣;
依次類推靖避,第i輪比較能夠確定第i大的元素,可知經(jīng)過N-1輪比較后我們能夠確定所有元素的位置(為什么不是N輪比較?——因?yàn)榍癗-1個大的元素確定了比默,還剩最后一個幻捏,自然就是最小的,無需再比較)

def bubble_sort(nums):
    if nums is not None:  # 注意判空,不要用=或者!=判空
        for i in range(1, len(nums)):  # 一共進(jìn)行1到N-1輪比較命咐,N即列表長度len(nums)
            is_sorted = True  # 用來判斷是否已經(jīng)排好序
            for j in range(len(nums) - i):  # 第i輪比較中需要比較第0,1,…,(N-i-1)個元素與其后面一個位置上的元素的大小
                if nums[j] > nums[j + 1]:
                    is_sorted = False  # 如果沒有發(fā)生交換篡九,則說明已經(jīng)排好序,無需進(jìn)行下一輪比較
                    nums[j], nums[j + 1] = nums[j + 1], nums[j]

            if is_sorted:
                break
    return nuts

2醋奠、選擇排序

基本思想:
遍歷元素榛臼,記錄下最小的元素所在的位置伊佃,然后把最小的元素和位置0上的元素互換;
一共進(jìn)行N-1輪遍歷:
第一輪確定第1小的元素沛善,放在位置0航揉;
第二輪確定第2小的元素,放在位置1金刁;x

第i輪確定第i小的元素帅涂,放在位置i;
N-1輪遍歷之后可以確定所有元素的正確位置尤蛮。

def select_sort(nums):
    if nums is not None:  # 注意判空

        for i in range(0, len(nums) - 1):  # 一共進(jìn)行0到N-2共N-1輪選擇媳友,N即列表長度len(nums)
            min_index = i  # 先初始化每輪選擇中最小的元素的位置為每輪遍歷的第一個元素
            for j in range(i + 1, len(nums)):  # 從第一個元素的下一個位置開始與記錄的最小元素做比較
                if nums[j] < nums[min_index]:
                    min_index = j

            if i != min_index:
                nums[i], nums[min_index] = nums[min_index], nums[i]

3、快速排序

基本思想:采用分而治之的思想抵屿,選取nums中的一個數(shù)作為基準(zhǔn)點(diǎn)庆锦,把要排序的數(shù)據(jù)分成兩部分捅位,一部分比基準(zhǔn)點(diǎn)小轧葛,一部分比基準(zhǔn)點(diǎn)大;
然后再對這兩部分?jǐn)?shù)據(jù)分別采用分而治之的方法進(jìn)行排序艇搀;
最后再把這幾部分?jǐn)?shù)據(jù)連接到一起尿扯。

def quick_sort(nums):

    if len(nums) <= 1:
        return nums

    pivot = nums[len(nums) // 2]
    left = [x for x in nums if x < pivot]
    middle = [x for x in nums if x == pivot]
    right = [x for x in nums if x > pivot]

    return quick_sort(left) + middle + quick_sort(right)

4、插入排序

基本思想:插入排序的原理類似于打撲克牌焰雕,把待排序數(shù)據(jù)分成兩部分衷笋,一部分是已排好序的有序數(shù)據(jù),一部分是亂序數(shù)據(jù)矩屁,
開始時(shí)默認(rèn)第一個數(shù)有序辟宗,然后再將后面的數(shù)逐個插入,插入操作具體包括:
1吝秕、與有序數(shù)據(jù)比較泊脐,確定插入位置,
2烁峭、在每次比較中將比待插入數(shù)據(jù)大的數(shù)據(jù)后移容客,給待插入數(shù)據(jù)騰位置

def insert_sort(nums):
    for i in range(len(nums)):
        preIndex = i-1  # 0到i-1的數(shù)據(jù)為已經(jīng)排好序的有序數(shù)據(jù)
        curnum = nums[i]  # 記錄下一個要插入到有序數(shù)據(jù)中的數(shù)

        # 遍歷有序數(shù)據(jù),找到curnum應(yīng)插入的位置
        while preIndex >= 0 and nums[preIndex] > curnum:  # 注意不要漏掉preIndex等于0
            nums[preIndex+1] = nums[preIndex]  # 比curnum大的數(shù)往后挪
            preIndex -= 1

        nums[preIndex+1] = curnum

    return nums

5约郁、希爾排序

基本思想:希爾排序是直接插入排序的升級版缩挑,減少插入排序的移動次數(shù)
插入排序在每次插入一個數(shù)據(jù)的過程中,湊要大量移動數(shù)據(jù)鬓梅,

希爾排序?qū)⑿蛄邪垂潭ㄩg隔劃分為多個子序列供置,在子序列中簡單插入排序,先做遠(yuǎn)距離移動使序列基本有序绽快;
逐漸縮小間隔重復(fù)操作芥丧,最后間隔為1時(shí)即簡單插入排序悲关。

def shell_insert(nums, d):
    n = len(nums)
    for i in range(d, n):
        j = i - d
        temp = nums[i]  # 記錄要插入的數(shù)
        while j >= 0 and nums[j] > temp:  # 從后向前,找到比其小的數(shù)的位置
            nums[j + d] = nums[j]  # 向后挪動
            j -= d
        if j != i - d:
            nums[j + d] = temp


def shell_sort(nums):

    n = len(nums)
    if n <= 1:
        return nums
    d = n//2
    while d >= 1:
        shell_insert(nums, d)
        d = d//2
    return nums

6娄柳、歸并排序

基本思想:歸并排序運(yùn)用分治遞歸思想:將大問題分為較小的子問題寓辱,分而治之;遞歸調(diào)用同樣的方法解決子問題赤拒。
最終將序列的排序問題分治為一個數(shù)的排序問題秫筏,關(guān)鍵在于如何將子問題答案合并為問題答案。

兩個有序序列合并為一個有序序列挎挖,借助一個暫存數(shù)組(列表)这敬,兩個序列元素依次比較填入暫存列表,形成一個有序序列蕉朵。
歸并排序劃分子問題采用二分法崔涂,共需O(logn)次劃分,當(dāng)然需要相當(dāng)次合并始衅;每次合并遍歷比較O(n)冷蚂。時(shí)間復(fù)雜度O(nlogn)。

def merge_sort(nums):
    import math
    if len(nums) < 2:
        return nums
    middle = math.floor(len(nums)/2)
    left, right = nums[0:middle], nums[middle:]
    return merge(merge_sort(left), merge_sort(right))

def merge(left, right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))

    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))

    return result

參考學(xué)習(xí):
十大排序算法總結(jié)Python3實(shí)現(xiàn)
python 十大經(jīng)典排序算法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汛闸,一起剝皮案震驚了整個濱河市蝙茶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌诸老,老刑警劉巖隆夯,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異别伏,居然都是意外死亡蹄衷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門厘肮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來愧口,“玉大人,你說我怎么就攤上這事轴脐〉鞅埃” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵大咱,是天一觀的道長恬涧。 經(jīng)常有香客問我,道長碴巾,這世上最難降的妖魔是什么溯捆? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上提揍,老公的妹妹穿的比我還像新娘啤月。我一直安慰自己,他們只是感情好劳跃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布谎仲。 她就那樣靜靜地躺著,像睡著了一般刨仑。 火紅的嫁衣襯著肌膚如雪郑诺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天杉武,我揣著相機(jī)與錄音辙诞,去河邊找鬼。 笑死轻抱,一個胖子當(dāng)著我的面吹牛飞涂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播祈搜,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼较店,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了夭问?” 一聲冷哼從身側(cè)響起泽西,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤曹铃,失蹤者是張志新(化名)和其女友劉穎缰趋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陕见,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秘血,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了评甜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灰粮。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖忍坷,靈堂內(nèi)的尸體忽然破棺而出粘舟,到底是詐尸還是另有隱情,我是刑警寧澤佩研,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布柑肴,位于F島的核電站,受9級特大地震影響旬薯,放射性物質(zhì)發(fā)生泄漏晰骑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一绊序、第九天 我趴在偏房一處隱蔽的房頂上張望硕舆。 院中可真熱鬧秽荞,春花似錦、人聲如沸抚官。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凌节。三九已至胁住,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刊咳,已是汗流浹背彪见。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留娱挨,地道東北人余指。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像跷坝,于是被迫代替她去往敵國和親酵镜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

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