排序方法——python

来源:https://www.cnblogs.com/fighting25/archive/2019/07/30/11271353.html
-Advertisement-
Play Games

1、冒泡排序法(Bubble Sort) 比較相鄰的元素。如果第一個比第二個大,就交換它們兩個; 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對,這樣在最後的元素應該會是最大的數; 針對所有的元素重覆以上的步驟,除了最後一個; 重覆步驟1~3,直到排序完成。 2、快速排序法(Quick ...


1、冒泡排序法(Bubble Sort)

  • 比較相鄰的元素。如果第一個比第二個大,就交換它們兩個;
  • 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對,這樣在最後的元素應該會是最大的數;
  • 針對所有的元素重覆以上的步驟,除了最後一個;
  • 重覆步驟1~3,直到排序完成。

def BubbleSort(lst):
    n=len(lst)
    if n<=1:
        return lst
    for i in range (0,n):
        for j in range(0,n-i-1):
            if lst[j]>lst[j+1]:
                (lst[j],lst[j+1])=(lst[j+1],lst[j])
    return lst

2、快速排序法(Quick Sort)

  • 從數列中挑出一個元素,稱為 “基準”(pivot);
  • 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱為分區(partition)操作;
  • 遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。

def QuickSort(lst):
    # 此函數完成分區操作
    def partition(arr, left, right):
        key = left  # 劃分參考數索引,預設為第一個數為基準數,可優化
        while left < right:
            # 如果列表後邊的數,比基準數大或相等,則前移一位直到有比基準數小的數出現
            while left < right and arr[right] >= arr[key]:
                right -= 1
            # 如果列表前邊的數,比基準數小或相等,則後移一位直到有比基準數大的數出現
            while left < right and arr[left] <= arr[key]:
                left += 1
            # 此時已找到一個比基準大的書,和一個比基準小的數,將他們互換位置
            (arr[left], arr[right]) = (arr[right], arr[left])
 
        # 當從兩邊分別逼近,直到兩個位置相等時結束,將左邊小的同基準進行交換
        (arr[left], arr[key]) = (arr[key], arr[left])
        # 返回目前基準所在位置的索引
        return left
 
    def quicksort(arr, left, right):  
        if left >= right:
            return
        # 從基準開始分區
        mid = partition(arr, left, right)
        # 遞歸調用
        # print(arr)
        quicksort(arr, left, mid - 1)
        quicksort(arr, mid + 1, right)
 
    # 主函數
    n = len(lst)
    if n <= 1:
        return lst
    quicksort(lst, 0, n - 1)
    return lst

3、插入排序(Insert Sort)

  • 從第一個元素開始,該元素可以認為已經被排序;
  • 取出下一個元素,在已經排序的元素序列中從後向前掃描;
  • 如果該元素(已排序)大於新元素,將該元素移到下一位置;
  • 重覆步驟3,直到找到已排序的元素小於或者等於新元素的位置;
  • 將新元素插入到該位置後;
  • 重覆步驟2~5。

def InsertSort(lst):
    n=len(lst)
    if n<=1:
        return lst
    for i in range(1,n):
        j=i
        target=lst[i]            #每次迴圈的一個待插入的數
        while j>0 and target<lst[j-1]:       #比較、後移,給target騰位置
            lst[j]=lst[j-1]
            j=j-1
        lst[j]=target            #把target插到空位
    return lst

4、希爾排序法(Shell Sort)

  • 選擇一個增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  • 按增量序列個數k,對序列進行k 趟排序;
  • 每趟排序,根據對應的增量ti,將待排序列分割成若幹長度為m 的子序列,分別對各子表進行直接插入排序。僅增量因數為1 時,整個序列作為一個表來處理,表長度即為整個序列的長度。

def ShellSort(lst):
    def shellinsert(arr,d):
        n=len(arr)
        for i in range(d,n):
            j=i-d
            temp=arr[i]             #記錄要出入的數
            while(j>=0 and arr[j]>temp):    #從後向前,找打比其小的數的位置
                arr[j+d]=arr[j]                 #向後挪動
                j-=d
            if j!=i-d:
                arr[j+d]=temp
    n=len(lst)
    if n<=1:
        return lst
    d=n//2
    while d>=1:
        shellinsert(lst,d)
        d=d//2
    return lst

 5、選擇排序法(Select Sort)

  • 初始狀態:無序區為R[1..n],有序區為空;
  • 第i趟排序(i=1,2,3…n-1)開始時,當前有序區和無序區分別為R[1..i-1]和R(i..n)。該趟排序從當前無序區中-選出關鍵字最小的記錄 R[k],將它與無序區的第1個記錄R交換,使R[1..i]和R[i+1..n)分別變為記錄個數增加1個的新有序區和記錄個數減少1個的新無序區;
  • n-1趟結束,數組有序化了。

def SelectSort(lst):
    n = len(lst)
    if n<=1:
        return lst
    for i in range(0,n-1):
        minIndex = i
        for j in range(i+1,n): #比較一遍,記錄索引不交換
            if lst[j]<lst[minIndex]:
                minIndex=j
        if minIndex!=i:
            (lst[minIndex],lst[i])=(lst[i],lst[minIndex])
    return lst

 6、堆積排序法(Heap Sort)

  • 將初始待排序關鍵字序列(R1,R2….Rn)構建成大頂堆,此堆為初始的無序區;
  • 將堆頂元素R[1]與最後一個元素R[n]交換,此時得到新的無序區(R1,R2,……Rn-1)和新的有序區(Rn),且滿足R[1,2…n-1]<=R[n];
  • 由於交換後新的堆頂R[1]可能違反堆的性質,因此需要對當前無序區(R1,R2,……Rn-1)調整為新堆,然後再次將R[1]與無序區最後一個元素交換,得到新的無序區(R1,R2….Rn-2)和新的有序區(Rn-1,Rn)。不斷重覆此過程直到有序區的元素個數為n-1,則整個排序過程完成

def  HeapSort(lst):
    def heapadjust(arr,start,end):  #將以start為根節點的堆調整為大頂堆
        temp=arr[start]
        son=2*start+1
        while son<=end:
            if son<end and arr[son]<arr[son+1]:  #找出左右孩子節點較大的
                son+=1
            if temp>=arr[son]:       #判斷是否為大頂堆
                break
            arr[start]=arr[son]     #子節點上移
            start=son                     #繼續向下比較
            son=2*son+1
        arr[start]=temp             #將原堆頂插入正確位置
#######
    n=len(lst)
    if n<=1:
        return lst
    #建立大頂堆
    root=n//2-1    #最後一個非葉節點(完全二叉樹中)
    while(root>=0):
        heapadjust(lst,root,n-1)
        root-=1
    #掐掉堆頂後調整堆
    i=n-1
    while(i>=0):
        (lst[0],lst[i])=(lst[i],lst[0])  #將大頂堆堆頂數放到最後
        heapadjust(lst,0,i-1)    #調整剩餘數組成的堆
        i-=1
    return lst

7、歸併排序法(Merge Sort)

  • 把長度為n的輸入序列分成兩個長度為n/2的子序列;
  • 對這兩個子序列分別採用歸併排序;
  • 將兩個排序好的子序列合併成一個最終的排序序列

def MergeSort(lst):
    #合併左右子序列函數
    def merge(arr,left,mid,right):
        temp=[]     #中間數組
        i=left          #左段子序列起始
        j=mid+1   #右段子序列起始
        while i<=mid and j<=right:
            if arr[i]<=arr[j]:
                temp.append(arr[i])
                i+=1
            else:
                temp.append(arr[j])
                j+=1
        while i<=mid:
            temp.append(arr[i])
            i+=1
        while j<=right:
            temp.append(arr[j])
            j+=1
        for i in range(left,right+1):    #  !註意這裡,不能直接arr=temp,他倆大小都不一定一樣
            arr[i]=temp[i-left]
    #遞歸調用歸併排序
    def mSort(arr,left,right):
        if left>=right:
            return
        mid=(left+right)//2
        mSort(arr,left,mid)
        mSort(arr,mid+1,right)
        merge(arr,left,mid,right)
 
    n=len(lst)
    if n<=1:
        return lst
    mSort(lst,0,n-1)
    return lst

8、基數排序法(Radix Sort)

  • 取得數組中的最大數,並取得位數;
  • arr為原始數組,從最低位開始取每個位組成radix數組;
  • 對radix進行計數排序(利用計數排序適用於小範圍數的特點);

import math
def RadixSort(lst):
    def getbit(x,i):       #返回x的第i位(從右向左,個位為0)數值
        y=x//pow(10,i)
        z=y%10
        return z
    def CountSort(lst):
        n=len(lst)
        num=max(lst)
        count=[0]*(num+1)
        for i in range(0,n):
            count[lst[i]]+=1
        arr=[]
        for i in range(0,num+1):
            for j in range(0,count[i]):
                arr.append(i)
        return arr
    Max=max(lst)
    for k in range(0,int(math.log10(Max))+1):             #對k位數排k次,每次按某一位來排
        arr=[[] for i in range(0,10)]
        for i in lst:                 #將ls(待排數列)中每個數按某一位分類(0-9共10類)存到arr[][]二維數組(列表)中
            arr[getbit(i,k)].append(i)
        for i in range(0,10):         #對arr[]中每一類(一個列表)  按計數排序排好
            if len(arr[i])>0:
                arr[i]=CountSort(arr[i])
        j=9
        n=len(lst)
        for i in range(0,n):     #順序輸出arr[][]中數到ls中,即按第k位排好
            while len(arr[j])==0:
                j-=1
            else:
                lst[n-1-i]=arr[j].pop()   
    return lst    

轉載鏈接:https://blog.csdn.net/weixin_41571493/article/details/81875088

 


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

-Advertisement-
Play Games
更多相關文章
  • 年薪20萬的夢想。。。 python對文件、目錄能做什麼?或者說我們需要python替我們做什麼?最經常的操作就是對文件的:打開、關閉、讀取、寫入、修改、保存等等對目錄的操作,無非就是:創建目錄、刪除目錄、更改目錄名字等等。我們先認識一下OS模塊,os模塊以及子模塊path中包含了獲取系統信息、以及 ...
  • request對象和request對象的原理 1.request和response對象request對象和request對象的原理時由伺服器創建的,我們來使用它們 2.request對象是來獲取請求消息,response對象是來設置響應消息 requset對象繼承體繫結構: ServletReque ...
  • SpringBoot讀取配置值的方式 方法一: @Value註解的方式取值 設定appliction.properties的配置信息 使用@Value取值 頁面展示 小明==》性別:boy 年齡:18 分數:98 方法二: 使用@ConfigurationProperties賦值給實體類 設定app ...
  • 一、Eureka基本架構 1、Eureka角色結構圖 角色職責如下: 1)、Register:服務註冊中心,它是一個Eureka Server ,提供服務註冊和發現功能。 2)、Provider:服務提供者,它是一個Eureka Client ,提供服務。 3)、Consumer:服務消費者,它是一 ...
  • 前言 前言 這篇文章的ArrayList源碼是基於jdk1.8版本的源碼,如果與前後版本的實現細節出現不一致的地方請自己多加註意。先上一個它的結構圖 ArrayList作為一個集合工具,對於我而言它值得我們註意的地方有: 那麼我就由這四個細節對ArrayList進行分析。 ArrayList的參數細 ...
  • C++ 基礎中的基礎 引用 引用的概念:引用變數是一個別名,也就是說,它是某個已存在變數的另一個名字。一旦把引用初始化為某個變數,就可以使用該引用名稱或變數名稱來指向變數。比如: 好,現在,我們定義了一個引用。並將其初始化為某個變數。這時,r就成了n的一個別名。你對r進行操作就相當於對n本尊進行操作 ...
  • 操作系統 : CentOS7.5.1804_x64 Python 版本 : 3.6.8 1、使用pip線上安裝 1.1 安裝單個package 格式如下: 示例如下: 1.2 安裝多個package 示例如下: req.txt 可以通過以下命令獲取: 1.3 線上安裝的其它問題 1.3.1 代理問題 ...
  • 第十章 資料庫 10.1 資料庫介紹 1、資料庫相關概念 資料庫伺服器:本質就是一個台電腦,該電腦之上安裝有資料庫管理軟體的服務端 資料庫管理系統RDBMS:本質就是一個C/S架構的套接字軟體 庫(文件夾)| 表(文件) 記錄:抽取一個事物所有典型的特征/數據 2、資料庫管理系統/軟體分類: 關 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...