首頁 後端開發 Python教學 用 python 實作各種排序演算法

用 python 實作各種排序演算法

Oct 18, 2016 am 09:15 AM

總結了一下常見集中排序的演算法

用 python 實作各種排序演算法

歸併排序

歸併排序也稱合併排序,是分治法的典型應用。分治思想是將每個問題分解成個小問題,將每個小問題解決,然後合併。

具體的歸併排序就是,將一組無序數依n/2遞歸分解成只有一個元素的子項,一個元素就是已經排好序的了。然後將這些有序的子元素進行合併。

合併的過程就是對兩個已經排好序的子序列,先選取兩個子序列中最小的元素進行比較,選取兩個元素中最小的那個子序列並將其從子序列中

去掉添加到最終的結果集中,直到兩個子序列歸併完成。

代碼如下:

#!/usr/bin/python  
import sys  
   
def merge(nums, first, middle, last):  
    ''''' merge '''  
    # 切片边界,左闭右开并且是了0为开始  
    lnums = nums[first:middle+1]   
    rnums = nums[middle+1:last+1]  
    lnums.append(sys.maxint)  
    rnums.append(sys.maxint)  
    l = 0  
    r = 0  
    for i in range(first, last+1):  
        if lnums[l] < rnums[r]:  
            nums[i] = lnums[l]  
            l+=1  
        else:  
            nums[i] = rnums[r]  
            r+=1  
def merge_sort(nums, first, last):  
    &#39;&#39;&#39;&#39;&#39; merge sort 
    merge_sort函数中传递的是下标,不是元素个数 
    &#39;&#39;&#39;  
    if first < last:  
        middle = (first + last)/2  
        merge_sort(nums, first, middle)  
        merge_sort(nums, middle+1, last)  
        merge(nums, first, middle,last)  
   
if __name__ == &#39;__main__&#39;:  
    nums = [10,8,4,-1,2,6,7,3]  
    print &#39;nums is:&#39;, nums  
    merge_sort(nums, 0, 7)  
    print &#39;merge sort:&#39;, nums
登入後複製

   

穩定,時間複雜度O(nlog n)

插入排序

代碼如下:

#!/usr/bin/python  
import sys  
   
def insert_sort(a):  
    &#39;&#39;&#39;&#39;&#39; 插入排序 
    有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数, 
    但要求插入后此数据序列仍然有序。刚开始 一个元素显然有序,然后插入一 
    个元素到适当位置,然后再插入第三个元素,依次类推 
    &#39;&#39;&#39;  
    a_len = len(a)  
    if a_len = 0 and a[j] > key:  
            a[j+1] = a[j]  
            j-=1  
        a[j+1] = key  
    return a  
   
if __name__ == &#39;__main__&#39;:  
    nums = [10,8,4,-1,2,6,7,3]  
    print &#39;nums is:&#39;, nums  
    insert_sort(nums)  
    print &#39;insert sort:&#39;, nums
登入後複製

   

穩定,時間複雜度O(n^2)

交換兩個元素的值python中你可以這麼寫:a, b = b, a,其實這是因為賦值符號的左右兩邊都是元組

(這裡需要強調的是,在python中,元組其實是由逗號“,”來界定的,而不是括號)。

選擇排序

選擇排序(Selection sort)是一種簡單直覺的排序演算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到

排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末端。以此類推,直到所

有元素均排序完畢。

import sys  
def select_sort(a):  
    &#39;&#39;&#39;&#39;&#39; 选择排序  
    每一趟从待排序的数据元素中选出最小(或最大)的一个元素, 
    顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 
    选择排序是不稳定的排序方法。 
    &#39;&#39;&#39;  
    a_len=len(a)  
    for i in range(a_len):#在0-n-1上依次选择相应大小的元素   
        min_index = i#记录最小元素的下标   
        for j in range(i+1, a_len):#查找最小值  
            if(a[j]<a[min_index]):  
                min_index=j  
        if min_index != i:#找到最小元素进行交换  
            a[i],a[min_index] = a[min_index],a[i]  
   
if __name__ == &#39;__main__&#39;:  
    A = [10, -3, 5, 7, 1, 3, 7]    
    print &#39;Before sort:&#39;,A    
    select_sort(A)    
    print &#39;After sort:&#39;,A
登入後複製

   

不穩定,時間複雜度 O(n^2)

希爾排序

希爾排序,也稱為遞減增量排序演算法,希爾排序是非穩定排序演算法。此方法又稱縮小增量排序,因DL. Shell於1959年提出而得名。

先取一個小於n的整數d1作為第一個增量,把檔案的全部記錄分成d1個組。所有距離為d1的倍數的記錄放在同一個組別中。先在各組內排序;

然後,取第二個增量d2

import sys  
def shell_sort(a):  
    &#39;&#39;&#39;&#39;&#39; shell排序  
    &#39;&#39;&#39;  
    a_len=len(a)  
    gap=a_len/2#增量  
    while gap>0:  
        for i in range(a_len):#对同一个组进行选择排序  
            m=i  
            j=i+1  
            while j<a_len:  
                if a[j]<a[m]:  
                    m=j  
                j+=gap#j增加gap  
            if m!=i:  
                a[m],a[i]=a[i],a[m]  
        gap/=2  
   
if __name__ == &#39;__main__&#39;:  
    A = [10, -3, 5, 7, 1, 3, 7]    
    print &#39;Before sort:&#39;,A    
    shell_sort(A)    
    print &#39;After sort:&#39;,A
登入後複製

   

不穩定,時間複雜度平均時間O(nlogn) 最差時間O(n^s)1

堆排序( Heap Sort )

"堆"起始索引為0 的「堆」中:

節點i 的右子節點在位置2 * i + 24) 節點i 的父節點在位置floor( (i - 1) / 2 )   : 註floor 表示「取整」操作

 堆的特性:

 每個節點的鍵值一定總是大於(或小於)它的父節點

「最大堆」:

「堆」的根節點保存的是鍵值最大的節點。即「堆」中每個節點的鍵值總是大於它的子節點。

 上移,下移:

當某節點的鍵值大於它的父節點時,這時我們就要進行「上移」操作,也就是我們把該節點移到它的父節點的位置,

而讓它的父節點到它的位置上,然後我們繼續判斷該節點,直到該節點不再大於它的父節點為止才停止「上移」。

現在我們再來了解一下「下移」操作。當我們把某節點的鍵值改小了之後,我們就要對其進行「下移」操作。

方法:

我們先建立一個最大堆(時間複雜度O(n)),然後每次我們只需要把根節點與最後一個位置的節點交換,然後把最後一個位置排除之外,然後把交換後根節點的堆進行調整(時間複雜度O(lgn) ),即對根節點進行「下移」操作即可。 堆排序的總的時間複雜度為O(nlgn).

程式碼如下:

#!/usr/bin env python  
   
# 数组编号从 0开始  
def left(i):  
    return 2*i +1  
def right(i):  
    return 2*i+2  
   
#保持最大堆性质 使以i为根的子树成为最大堆  
def max_heapify(A, i, heap_size):  
    if heap_size <= 0:  
        return   
    l = left(i)  
    r = right(i)  
    largest = i # 选出子节点中较大的节点  
    if l  A[largest]:  
        largest = l  
    if r  A[largest]:  
        largest = r  
    if i != largest :#说明当前节点不是最大的,下移  
        A[i], A[largest] = A[largest], A[i] #交换  
        max_heapify(A, largest, heap_size)#继续追踪下移的点  
    #print A  
# 建堆    
def bulid_max_heap(A):  
    heap_size = len(A)  
    if heap_size >1:  
        node = heap_size/2 -1  
        while node >= 0:  
           max_heapify(A, node, heap_size)  
           node -=1  
   
# 堆排序 下标从0开始  
def heap_sort(A):  
    bulid_max_heap(A)  
    heap_size = len(A)  
    i = heap_size - 1   
    while i > 0 :  
        A[0],A[i] = A[i], A[0] # 堆中的最大值存入数组适当的位置,并且进行交换  
        heap_size -=1 # heap 大小 递减 1  
        i -= 1 # 存放堆中最大值的下标递减 1  
        max_heapify(A, 0, heap_size)  
   
if __name__ == &#39;__main__&#39; :  
   
    A = [10, -3, 5, 7, 1, 3, 7]  
    print &#39;Before sort:&#39;,A  
    heap_sort(A)  
    print &#39;After sort:&#39;,A
登入後複製

   

不穩定,時間複雜度O(nlog n)

演算法快速排序

不穩定,時間複雜度O(nlog n)

演算法快速排序

一樣,也是基於分治模式。子數組A[p...r]快速排序的分治過程的三個步驟為:

分解:把數組A[p...r]分為A[p...q-1]與A[q+1...r]兩部分,其中A[p...q-1]中的每個元素都小於等於A[q]而A[q+1...r]中的每個元素都大於等於A[q];

解決:透過遞歸呼叫快速排序,對子數組A[p...q-1]和A[q+1...r]進行排序;

合併:因為兩個子數組是就地排序的,所以不需要額外的運算。

對於劃分partition 每一輪迭代的開始,x=A[r], 對於任何數組下標k,有:

1) 如果p≤k≤i,則A[k]≤x。

2) 如果i+1≤k≤j-1,則A[k]>x。

3) 如果k=r,則A[k]=x。

程式碼如下:

#!/usr/bin/env python  
# 快速排序  
&#39;&#39;&#39;&#39;&#39; 
划分 使满足 以A[r]为基准对数组进行一个划分,比A[r]小的放在左边, 
   比A[r]大的放在右边 
快速排序的分治partition过程有两种方法, 
一种是上面所述的两个指针索引一前一后逐步向后扫描的方法, 
另一种方法是两个指针从首位向中间扫描的方法。 
&#39;&#39;&#39;  
#p,r 是数组A的下标  
def partition1(A, p ,r):  
    &#39;&#39;&#39;&#39;&#39; 
      方法一,两个指针索引一前一后逐步向后扫描的方法 
    &#39;&#39;&#39;  
    x = A[r]  
    i = p-1  
    j = p  
    while j < r:  
        if A[j] < x:  
            i +=1  
            A[i], A[j] = A[j], A[i]  
        j += 1  
    A[i+1], A[r] = A[r], A[i+1]  
    return i+1  
   
def partition2(A, p, r):  
    &#39;&#39;&#39;&#39;&#39; 
    两个指针从首尾向中间扫描的方法 
    &#39;&#39;&#39;  
    i = p  
    j = r  
    x = A[p]  
    while i = x and i < j:  
            j -=1  
        A[i] = A[j]  
        while A[i]<=x and i < j:  
            i +=1  
        A[j] = A[i]  
    A[i] = x  
    return i  
   
# quick sort  
def quick_sort(A, p, r):  
    &#39;&#39;&#39;&#39;&#39; 
        快速排序的最差时间复杂度为O(n2),平时时间复杂度为O(nlgn) 
    &#39;&#39;&#39;  
    if p < r:  
        q = partition2(A, p, r)  
        quick_sort(A, p, q-1)  
        quick_sort(A, q+1, r)  
   
if __name__ == &#39;__main__&#39;:  
   
    A = [5,-4,6,3,7,11,1,2]  
    print &#39;Before sort:&#39;,A  
    quick_sort(A, 0, 7)  
    print &#39;After sort:&#39;,A
登入後複製

   

🎜🎜

不穩定,時間複雜度最理想O(nlogn)最差時間O(n^2)

說下python中的序列:

列表、元組和字串都是序列,但是序列是什麼,它們為什麼如此特別呢?序列的兩個主要特點是索引操作符和切片操作符。索引操作符讓我們可以從序列中抓取一個特定項目。切片運算子讓我們能夠取得序列的一個切片,即一部分序列,如:a = ['aa','bb','cc'], print a[0] 為索引操作,print a[0:2]為切片操作。


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1325
25
PHP教程
1273
29
C# 教程
1252
24
Python vs.C:申請和用例 Python vs.C:申請和用例 Apr 12, 2025 am 12:01 AM

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

Python:遊戲,Guis等 Python:遊戲,Guis等 Apr 13, 2025 am 12:14 AM

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

Python與C:學習曲線和易用性 Python與C:學習曲線和易用性 Apr 19, 2025 am 12:20 AM

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

Python和時間:充分利用您的學習時間 Python和時間:充分利用您的學習時間 Apr 14, 2025 am 12:02 AM

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python vs.C:探索性能和效率 Python vs.C:探索性能和效率 Apr 18, 2025 am 12:20 AM

Python在開發效率上優於C ,但C 在執行性能上更高。 1.Python的簡潔語法和豐富庫提高開發效率。 2.C 的編譯型特性和硬件控制提升執行性能。選擇時需根據項目需求權衡開發速度與執行效率。

Python標準庫的哪一部分是:列表或數組? Python標準庫的哪一部分是:列表或數組? Apr 27, 2025 am 12:03 AM

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。

Python:自動化,腳本和任務管理 Python:自動化,腳本和任務管理 Apr 16, 2025 am 12:14 AM

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

學習Python:2小時的每日學習是否足夠? 學習Python:2小時的每日學習是否足夠? Apr 18, 2025 am 12:22 AM

每天學習Python兩個小時是否足夠?這取決於你的目標和學習方法。 1)制定清晰的學習計劃,2)選擇合適的學習資源和方法,3)動手實踐和復習鞏固,可以在這段時間內逐步掌握Python的基本知識和高級功能。

See all articles