Python經典排序演算法

来源:https://www.cnblogs.com/yongestcat/archive/2019/12/28/12073317.html
-Advertisement-
Play Games

https://www.cnblogs.com/onepixel/p/7674659.html這個文章很nicehttps://www.bilibili.com/video/av685670?from=search&seid=1637373535603658338這個動圖優秀https://www.... ...


https://www.cnblogs.com/onepixel/p/7674659.html這個文章很nice

https://www.bilibili.com/video/av685670?from=search&seid=1637373535603658338這個動圖優秀

https://www.icourse163.org/course/ZJU-93001   MOOC浙大 數據結構 陳越、何欽銘


冒泡排序、選擇排序、插入排序這三個是最慢也是最經典的三個排序演算法

快速排序對於大的亂數串列一般相信是最快的已知排序

冒泡排序 bubble sort

最簡單的排序演算法,也是效率最差的,因為它必須在最終位置知道前交換,浪費許多“交換操作”

如果列表已經排序,則是最好情況,遍歷期間無需交換,如果發現已經排序,可以提前終止,這種修改下的冒泡通常稱為短冒泡排序


時間複雜度: 平均O(n^2)    最差O(n^2)     最好O(n)

空間複雜度:O(1)

穩定

#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]

#冒泡排序
for i in range(len(alist)-1):
    for j in range(len(alist)-1-i):
        if alist[j] > alist[j+1]:
            alist[j],alist[j+1] = alist[j+1],alist[j]
        
#排序結果輸出
print('sorted:',alist)

選擇排序 selection sort

選擇排序改進了冒泡排序,每次遍歷列表只做一次交換


時間複雜度:平均O(n^2)    最差O(n^2)    最好O(n^2)

空間複雜度:O(1)

不穩定

#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]

#選擇排序
for i in range(len(alist)-1):
    least = i
    for j in range(i+1,len(alist)):
        if alist[j] < alist[least]:
            least = j
    if least != i:
        alist[least],alist[i] = alist[i],alist[least]

#排序結果輸出
print('sorted:',alist)

插入排序 insertion sort

它始終在列表的較低位置維護一個排序的子列表,然後將每個新項 “插入” 回先前的子列表,使得排序的子列表成為較大的一個項


時間複雜度: 平均O(n^2)    最差O(n^2)     最好O(n)

空間複雜度:O(1)

穩定

#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]

#插入排序
for i in range(1,len(alist)):
    j = i;
    while j>0 and alist[j-1]>alist[j]:
        alist[j-1],alist[j] = alist[j],alist[j-1]
        j -= 1
        
#排序結果輸出
print('sorted:',alist)

希爾排序 shell sort

是1959年Shell發明,第一個突破O(n^2)的排序,是對簡單插入排序的改進,與插入排序不同的是它優先比較距離較遠的元素,又叫“遞減增量排序”

是針對插入排序以下2特點改進:在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率;一般來說是低效的,因為插入排序每次只能將數據移動一位

希爾排序通過將比較的全部元素分為幾個區域來提升插入排序的性能。這樣可以讓一個元素可以一次性地朝最終位置前進一大步

gap概念,gap遞減,最後一步就是插入排序,但是此時幾乎已經排好序了

gap是希爾排序核心

出名的gap設置Marcin Ciura's gap sequence ,gaps = [701, 301, 132, 57, 23, 10, 4, 1],不過下麵例子用數組長度不斷整除2得到的序列作為gaps


時間複雜度:平均O(n(logn)^2)    最差O(n^2)    最好O(n)

空間複雜度:O(1)

不穩定

#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]

#希爾排序
gap = len(alist)//2
while gap>0:
    #對每個gap做插入排序
    for i in range(gap,len(alist)):
        j = i
        while j>=gap and alist[j-gap]>alist[j]:
            alist[j-gap],alist[j] = alist[j],alist[j-gap]
            j -= gap           
    gap = gap//2

#排序結果輸出
print('sorted:',alist)

歸併排序 merge sort

分而治之的策略來提高性能,是分治法的典型應用

歸併排序是一種遞歸演算法,不斷將列表拆分為一半

二路歸併 多路歸併

缺點是在合併過程需要額外存儲空間


時間複雜度: 平均O(nlogn)    最差O(nlogn)      最好O(nlogn)

空間複雜度:O(n)

穩定

#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]

#歸併排序
def merge_sort(ilist):   
    def merge(left, right):
        result = []
        while left and right:
            result.append((left if left[0] <= right[0] else right).pop(0))
        return result + left + right
    
    if len(ilist) <= 1:
        return ilist
    mid = len(ilist) // 2
    return merge(merge_sort(ilist[:mid]), merge_sort(ilist[mid:]))

#排序結果輸出
print('sorted:',merge_sort(alist))

快速排序 quick sort

與歸併排序相同,採用分治法,而不使用額外存儲

是對冒泡排序的改進

通常明顯比其他演算法更快,因為它的內部迴圈可以在大部分的架構上很有效的達成

簡單的版本和歸併排序一樣不好,需要額外存儲空間,但是可以改為in-place版本,也就不要額外空間了


時間複雜度: 平均O(nlogn)    最差O(n^2)      最好O(nlogn)

空間複雜度:O(nlogn)

不穩定

#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]

#快速排序
def quick_sort(ilist): 
    length = len(ilist)
    if length <= 1:
        return ilist
    else:
        # Use the last element as the first pivot
        pivot = ilist.pop()
        # Put elements greater than pivot in greater list
        # Put elements lesser than pivot in lesser list
        greater, lesser = [], []
        for element in ilist:
            if element > pivot:
                greater.append(element)
            else:
                lesser.append(element)
        return quick_sort(lesser) + [pivot] + quick_sort(greater)

#排序結果輸出
print('sorted:',quick_sort(alist))

堆排序 heap sort

是對選擇排序的一種改進

利用堆這種數據結構所設計的演算法 近似完全二叉樹

堆通常通過一維數組實  大根堆  小根堆


時間複雜度:平均O(nlogn)    最差O(nlogn)      最好O(nlogn)

空間複雜度:O(1)

不穩定

#測試輸入數組
alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]

#堆排序
def heapify(unsorted, index, heap_size):
    largest = index
    left_index = 2 * index + 1
    right_index = 2 * index + 2
    if left_index < heap_size and unsorted[left_index] > unsorted[largest]:
        largest = left_index

    if right_index < heap_size and unsorted[right_index] > unsorted[largest]:
        largest = right_index

    if largest != index:
        unsorted[largest], unsorted[index] = unsorted[index], unsorted[largest]
        heapify(unsorted, largest, heap_size)
        
def heap_sort(unsorted):
    n = len(unsorted)
    for i in range(n // 2 - 1, -1, -1):
        heapify(unsorted, i, n)
    for i in range(n - 1, 0, -1):
        unsorted[0], unsorted[i] = unsorted[i], unsorted[0]
        heapify(unsorted, 0, i)
    return unsorted

#排序結果輸出
print('sorted:',heap_sort(alist))

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Struts2整合AJAX有2種方式: 使用type="stream"類型的<result> 使用JSON插件 使用type="stream"類型的<result> 獲取text 前端 <body> <form> 學號:<input type="text" id="no"><br /> 姓名:<in ...
  • 將pip的下載源換成國內的,速度會有很大的提升。 下麵是一些國內常用鏡像: 阿裡雲 http://mirrors.aliyun.com/pypi/simple/ 中國科技大學 https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣(douban) http://pyp ...
  • ArrayList和LinkedList的區別 步驟 1 : ArrayList和LinkedList的區別 ArrayList , 插入,刪除數據慢 LinkedList, 插入,刪除數據快 ArrayList是順序結構,所以 定位很快 ,指哪找哪。 就像電影院位置一樣,有了電影票,一下就找到位置 ...
  • Cookie Cookie 是一種伺服器發送給瀏覽器以鍵值對形式存儲小量信息的技術。 當瀏覽器首次請求伺服器時,伺服器會將一條信息封裝成一個Cookie發送給瀏覽器,瀏覽器收到Cookie,會將它保存在記憶體中(註意這裡的記憶體是本機記憶體,而不是伺服器記憶體)或者本地文件,那之後每次向伺服器發送請求,瀏覽 ...
  • Java ArrayList和HashSet的區別 示例 1 : 是否有順序 ArrayList: 有順序 HashSet: 無順序 HashSet的具體順序,既不是按照插入順序,也不是按照hashcode的順序。 以下是 HasetSet源代碼 中的部分註釋 / It makes no guara ...
  • 運行環境:centos 7,jdk 1.8 問題一: 原因:無法創建本地文件問題,用戶最大可創建文件數太小 解決方案:切換到root用戶,編輯limits.conf配置文件, 添加類似如下內容: vim /etc/security/limits.conf 添加如下內容:* soft nofile 6 ...
  • 最近又學到了很多新知識,感謝優銳課老師細緻地講解,這篇博客記錄下自己所學所想。 想更多地瞭解Spring Boot項目中的功能測試嗎?這篇文章帶你瞭解有關在測試中使用Docker容器的更多信息。 本文重點介紹在Spring Boot應用程式的功能測試期間應用一些最佳實踐。我們將演示一種高級方法,該方 ...
  • [TOC] SpringBoot如何優雅的使用RocketMQ MQ,是一種跨進程的通信機制,用於上下游傳遞消息。在傳統的互聯網架構中通常使用MQ來對上下游來做解耦合。 舉例:當A系統對B系統進行消息通訊,如A系統發佈一條系統公告,B系統可以訂閱該頻道進行系統公告同步,整個過程中A系統並不關係B系統 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...