Python常用排序算法

1. 冒泡排序

冒泡排序是一種簡單的排序算法,它重復地遍歷要排序的列表,比較相鄰的元素,如果他們的順序錯誤就交換他們。

def bubble_sort(arr):# 遍歷所有數組元素for i in range(len(arr)):# 最后i個元素是已經排序好的for j in range(0, len(arr)-i-1):# 如果當前元素大于下一個元素,則交換位置if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]return arrarr = [11, 32, 21, 67, 54, 19]
sorted_arr = bubble_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [11, 19, 21, 32, 54, 67]

復雜度分析

  1. 時間復雜度:
  • 最壞情況:O(n2)(完全逆序)
  • 最好情況:O(n)
  • 平均情況:O(n2)
  1. 空間復雜度:O(1)(原地排序)

2. 選擇排序

選擇排序是一種簡單直觀的排序算法,它的工作原理是每次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的數據元素排序完畢。

def select_sort(arr):# 遍歷所有數組元素for i in range(len(arr)):# 找到剩余未排序部分的最小元素索引min_index = ifor j in range(i+1, len(arr)):if arr[j] < arr[min_index]:min_index = j# 將找到的最小元素與第i個位置的元素交換arr[i], arr[min_index] =  arr[min_index], arr[i]return arrarr = [11, 32, 21, 67, 54, 19]
sorted_arr = select_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [11, 19, 21, 32, 54, 67]

復雜度分析

  1. 時間復雜度:O(n2)
  2. 空間復雜度:O(1)(原地排序)

3. 插入排序

插入排序是一種簡單直觀的排序算法,它的工作原理是通過構建有序序列,在已排序序列中從后向前掃描,找到相應位置并插入。

def insert_sort(arr):# 遍歷從1到倒數第二個元素for i in range(1, len(arr)):# 當前需要插入的元素key = arr[i]# 已排序部分的最后一個元素索引j = i - 1# 將arr[i]與已排序部分的元素逐個比較,如果比key大則后移一位while j >= 0 and key < arr[j]:arr[j + 1] = arr[j]j -= 1# 找到合適位置,插入keyarr[j + 1] = keyreturn arrarr = [11, 32, 21, 67, 54, 19]
sorted_arr = insert_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [11, 19, 21, 32, 54, 67]

復雜度分析

  1. 時間復雜度:
  • 最壞情況:O(n2)(當數組是逆序時)
  • 最好情況:O(n)(當數組已經有序時)
  • 平均情況:O(n2)
  1. 空間復雜度:O(1)(原地排序)

4. 快速排序

快速排序是一種高效的排序算法,采用分治法策略。首先任意選取一個元素作為基準數據,將待排序列表中的數據分割成獨立的兩部分,比基準數據小的放在它左邊,比基準數據大的放在它右邊,此時第一輪數據排序完成。然后再按照此方法對兩邊的數據分別進行分割,直至被分割的數據只有一個或者零個時,遞歸結束。

def quick_sort(arr):if len(arr) <= 1:return arr# 選擇中間元素作為基準值pivot = arr[len(arr)//2]left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]right = [x for x in arr if x > pivot]return quick_sort(left) + middle + quick_sort(right)arr = [11, 32, 21, 67, 54, 19]
sorted_arr = quick_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [11, 19, 21, 32, 54, 67]

復雜度分析

  1. 時間復雜度:
  • 最壞情況:O(n2)(當分區極度不平衡時)
  • 最好情況:O(n log n)
  • 平均情況:O(n log n)
  1. 空間復雜度:O(n)(創建了新的列表)

5. 歸并排序

歸并排序是一種基于分治策略的高效排序算法,將數組不斷地分成兩半,然后遞歸地對兩半進行排序,最后將排序好的兩半合并在一起。

def merge_sort(arr):if len(arr) <= 1:return arr# 分割階段mid = len(arr) // 2left = merge_sort(arr[:mid])right = merge_sort(arr[mid:])# 合并階段return merge(left, right)def merge(left, right):"""合并兩個已排序的列表"""result = []i = j = 0while i < len(left) and j < len(right):if left[i] < right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1# 添加剩余元素result.extend(left[i:])result.extend(right[j:])return resultarr = [38, 27, 43, 3, 9, 82, 10]
sorted_arr = merge_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [3, 9, 10, 27, 38, 43, 82]

復雜度分析

  1. 時間復雜度:O(n log n)
  2. 空間復雜度: O(n)(需要額外空間存儲臨時數組)

6. 堆排序

堆排序是一種基于二叉堆數據結構的高效排序算法。堆是一種特殊的完全二叉樹,其中每個父節點的值都大于或等于其子節點的值(稱為最大堆)或每個父節點的值都小于或等于其子節點的值(稱為最小堆)。

import heapqdef heap_sort(arr):# 構建最小堆heapq.heapify(arr)return [heapq.heappop(arr) for _ in range(len(arr))]arr = [12, 11, 15, 3, 21, 9]
sorted_arr = heap_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [3, 9, 11, 12, 15, 21]

復雜度分析

  1. 時間復雜度:
  • 建堆過程:O(n)
  • 每次堆化:O(log n)
  • 總體時間復雜度:O(n log n)
  1. 空間復雜度: O(1)(原地排序)

7. 計數排序

計數排序是一種非比較排序算法,適用于對一定范圍內的整數進行排序。它統計數組中每個元素出現的次數,然后根據統計結果將元素放回正確的位置。

def count_sort(arr):if len(arr) == 0:return arr# 找到數組中的最大值和最小值max_val = max(arr)min_val = min(arr)# 創建計數數組,初始化為0count = [0] * (max_val - min_val + 1)# 統計每個元素出現的次數for num in arr:count[num - min_val] += 1# 重建排序后的數組sorted_arr = []for i in range(len(count)):sorted_arr.extend([i + min_val] * count[i])return sorted_arrarr = [4, 2, 5, 1, 8]
sorted_arr = count_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [1, 2, 4, 5, 8]

復雜度分析

  1. 時間復雜度:O(n+k),其中n是元素數量,k是數據范圍
  2. 空間復雜度:O(n+k)

8. 基數排序

基數排序是一種非比較型整數排序算法,它通過將整數按位切割成不同的數字,然后按每個位數分別比較排序。基數排序可以采用最低位優先(LSD)或最高位優先(MSD)兩種方式。

def radix_sort(arr):# 找到數組中的最大數,確定排序的輪數max_num = max(arr)# 從個位開始exp = 1while max_num // exp > 0:counting_sort_by_digit(arr, exp)exp *= 10return arrdef counting_sort_by_digit(arr, exp):n = len(arr)output = [0] * ncount = [0] * 10# 統計當前位數的數字出現次數for num in arr:digit = (num // exp) % 10count[digit] += 1# 計算累加計數for i in range(1, 10):count[i] += count[i-1]# 反向填充輸出數組(保證穩定性)for i in range(n-1, -1, -1):digit = (arr[i] // exp) % 10output[count[digit] - 1] = arr[i]count[digit] -= 1# 將排序結果復制回原數組for i in range(n):arr[i] = output[i]arr = [170, 45, 75, 90, 802, 24, 2, 66]
sorted_arr = radix_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [2, 24, 45, 66, 75, 90, 170, 802]

復雜度分析

  1. 時間復雜度:O(d*(n+k)),其中d是最大數字的位數,n是元素數量,k是基數
  2. 空間復雜度:O(n+k)

9. 桶排序

桶排序是一種分布式排序算法,它將元素分到有限數量的桶里,每個桶再分別排序。

def bucket_sort(arr, bucket_size=5):if len(arr) == 0:return arr# 找到最大值和最小值max_val = max(arr)min_val = min(arr)# 計算桶的數量bucket_count = (max_val - min_val) // bucket_size + 1buckets = [[] for _ in range(bucket_count)]# 將元素分配到各個桶中for num in arr:index = (num - min_val) // bucket_sizebuckets[index].append(num)# 對每個桶進行排序sorted_arr = []for bucket in buckets:# 使用內置的sorted函數sorted_arr.extend(sorted(bucket))return sorted_arrarr = [29 ,25, 13, 21, 8, 43]
sorted_arr = bucket_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [8, 13, 21, 25, 29, 43]

復雜度分析

  1. 時間復雜度:
  • 平均情況:O(n+k),其中k是桶的數量
  • 最壞情況:O(n2)(當所有元素都分配到同一個桶中)
  1. 空間復雜度:O(n+k)

10. 希爾排序

希爾排序是插入排序的一種高效改進版本,也稱為縮小增量排序。它通過將原始列表分割成多個子列表來進行插入排序,隨著算法的進行,子列表的長度逐漸增大,最終整個列表變為一個子列表完成排序。

def shell_sort(arr):n = len(arr)# 初始間隔(gap)設置為數組長度的一半gap = n // 2while gap > 0:# 對各個間隔分組進行插入排序for i in range(gap, n):temp = arr[i]j = i# 對子列表進行插入排序while j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = temp# 縮小間隔gap = gap // 2return arrarr = [9 , 8, 3, 6, 5, 7, 1]
sorted_arr = shell_sort(arr)
print("排序后為:", sorted_arr)

輸出結果:
排序后為: [1, 3, 5, 6, 7, 8, 9]

復雜度分析

  1. 時間復雜度:
  • 平均情況:O(n1.3)到O(n1.5)
  • 最壞情況:O(n*n)
  • 最好情況:O(n log n)
  1. 空間復雜度:O(1)(原地排序)

11. 拓撲排序

拓撲排序是針對有向無環圖的線性排序算法,使得對于圖中的每一條有向邊(u, v),u在排序中總是位于v的前面。

from collections import dequedef topo_sort_kahn(graph):# 計算所有節點的入度in_degree = {node: 0 for node in graph}for node in graph:for neighbor in graph[node]:in_degree[neighbor] += 1# 初始化隊列,將所有入度為0的節點加入隊列queue = deque([node for node in graph if in_degree[node] == 0])topo_order = []while queue:current = queue.popleft()topo_order.append(current)# 減少所有鄰居的入度for neighbor in graph[current]:in_degree[neighbor] -= 1# 如果鄰居的入度變為0,加入隊列if in_degree[neighbor] == 0:queue.append(neighbor)# 檢查是否所有節點都被排序(無環)if len(topo_order) == len(graph):return topo_orderelse:return []  # 圖中存在環,無法進行拓撲排序
# 定義有向無環圖(鄰接表表示)
graph = {'A': ['B', 'C'],'B': ['D', 'E'],'C': ['F'],'D': [],'E': ['F'],'F': []
}print("Kahn算法拓撲排序結果:", topo_sort_kahn(graph))

輸出結果:
Kahn算法拓撲排序結果: [‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’]

復雜度分析

  1. 時間復雜度:O(V+E),其中V是頂點數,E是邊數
  2. 空間復雜度:O(V)(存儲入度或遞歸棧)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75333.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75333.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75333.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解鎖塔能科技,開啟工廠綠色轉型與可持續發展雙引擎

在全球積極推進可持續發展的大背景下&#xff0c;能源的高效利用與節能減排&#xff0c;已成為各行各業邁向高質量發展進程中無法回避的核心任務。工廠作為能源消耗大戶與污染排放重點源頭&#xff0c;其綠色轉型迫在眉睫&#xff0c;這不僅關乎企業自身的長遠發展&#xff0c;…

Spring Boot 線程池配置詳解

Spring Boot 線程池配置詳解 一、核心配置參數及作用 基礎參數核心線程數 (corePoolSize)? 作用?:線程池中始終保持存活的線程數量,即使空閑也不回收?。 建議?:根據任務類型設定(如 I/O 密集型任務可設為 CPU 核心數 2)?。 最大線程數 (maxPoolSize)? 作用?:…

入侵檢測系統(IDS)和入侵防御系統(IPS)有啥區別?

入侵檢測系統&#xff08;IDS&#xff09;和入侵防御系統&#xff08;IPS&#xff09;是網絡安全中的兩種關鍵技術&#xff0c;它們的核心區別在于 檢測后的響應方式 和 部署位置。以下是詳細對比&#xff1a; 1. 核心功能 - IDS&#xff08;入侵檢測系統&#xff09; - 僅監…

【MySQL 數據庫】數據表的操作

&#x1f525;博客主頁&#x1f525;&#xff1a;【 坊鈺_CSDN博客 】 歡迎各位點贊&#x1f44d;評論?收藏? 目錄 1. 表的查看 1.1 語法 2. 表的創建 2.1 語法 2.2 練習 3. 查看表結構 3.1 語法 3.2 示例 4. 表的修改 4.1 語法 4.2 示例操作 4.2.1 向表中添加字段…

sqli-labs靶場 less5

文章目錄 sqli-labs靶場less 5 報錯注入 sqli-labs靶場 每道題都從以下模板講解&#xff0c;并且每個步驟都有圖片&#xff0c;清晰明了&#xff0c;便于復盤。 sql注入的基本步驟 注入點注入類型 字符型&#xff1a;判斷閉合方式 &#xff08;‘、"、’、“”&#xf…

C# 狀態模式深度解析:構建靈活的狀態驅動系統

一、狀態模式概述 狀態模式&#xff08;State Pattern&#xff09;是一種行為型設計模式&#xff0c;它允許對象在其內部狀態改變時改變其行為&#xff0c;使對象看起來像是修改了它的類。這種模式將特定狀態相關的行為局部化&#xff0c;并且將不同狀態的行為分割開來。 狀態…

vue實現二維碼生成器和解碼器

vue實現二維碼生成器和解碼器 1.生成基本二維碼&#xff1a;根據輸入的value生成二維碼。 2.可定制尺寸&#xff1a;通過size調整大小。 3.顏色和背景色&#xff1a;設置二維碼顏色和背景。 4.靜區&#xff08;quiet zone&#xff09;支持&#xff1a;通過quietZone調整周圍的…

Nacos:Nacos服務注冊與服務發現超詳細的源碼解析(二)

&#x1fa81;&#x1f341; 希望本文能給您帶來幫助&#xff0c;如果有任何問題&#xff0c;歡迎批評指正&#xff01;&#x1f405;&#x1f43e;&#x1f341;&#x1f425; 文章目錄 一、背景二、環境與依賴三、服務注冊與服務發現總流程圖四、服務注冊源碼4.1 客戶端4.1.1…

ECMAScript 6 新特性(二)

ECMAScript 6 新特性&#xff08;二&#xff09; ECMAScript 6 新特性&#xff08;一&#xff09; ECMAScript 6 新特性&#xff08;二&#xff09;&#xff08;本文&#xff09; ECMAScript 7~10 新特性 1. 生成器 生成器函數是 ES6 提供的一種解決異步編程方案&#xff0c;一…

深入理解 RxSwift 中的 Driver:用法與實踐

目錄 前言 一、什么是Driver 1.不會發出錯誤 2.主線程保證 3.可重放 4.易于綁定 二、Driver vs Observable 三、使用場景 1.綁定數據到UI控件 2.響應用戶交互 3.需要線程安全的邏輯 4.如何使用Driver? 1.綁定文本輸入到Label 2.處理按鈕點擊事件 3.從網絡請求…

Linux自行實現的一個Shell(15)

文章目錄 前言一、頭文件和全局變量頭文件全局變量 二、輔助函數獲取用戶名獲取主機名獲取當前工作目錄獲取最后一級目錄名生成命令行提示符打印命令行提示符 三、命令處理獲取用戶輸入解析命令行執行外部命令 四、內建命令添加環境變量檢查和執行內建命令 五、初始化初始化環境…

RocketMQ和kafka 的區別

一、數據可靠性與容錯機制 數據可靠性 RocketMQ支持同步刷盤和同步復制&#xff0c;確保消息寫入磁盤后才返回確認&#xff0c;單機可靠性高達10個9&#xff0c;即使操作系統崩潰也不會丟失數據。而Kafka默認采用異步刷盤和異步復制&#xff0c;雖然吞吐量高&#xff0c;但極端…

在 openEuler 24.03 (LTS) 操作系統上添加 ollama 作為系統服務的步驟

以下是在 openEuler 操作系統上添加 ollama 作為系統服務的步驟&#xff1a; 創建 systemd 服務文件 sudo vi /etc/systemd/system/ollama.service將以下內容寫入服務文件&#xff08;按需修改參數&#xff09;&#xff1a; [Unit] DescriptionOllama Service Afternetwork.…

光譜相機的關鍵技術參數

光譜相機的關鍵技術參數直接影響其數據獲取能力和應用場景適配性。以下是核心參數的詳細解析&#xff0c;涵蓋光譜性能、空間性能、硬件性能及環境適應性&#xff1a; 一、光譜性能參數? ?1. 光譜范圍&#xff08;Spectral Range&#xff09;? ?定義?&#xff1a;相機可…

ARM內核與寄存器

ARM內核與寄存器詳解 目錄 ARM架構概述ARM處理器模式 Cortex-M3內核的處理器模式Cortex-A系列處理器模式 ARM寄存器集 通用寄存器程序計數器(PC)鏈接寄存器(LR)堆棧指針(SP)狀態寄存器(CPSR/SPSR) 協處理器寄存器NEON和VFP寄存器寄存器使用規范常見ARM指令與寄存器操作 ARM架…

Git 拉取時常見沖突及解決方法總結

Git 拉取時常見沖突及解決方法總結 一、常見錯誤場景1. 本地修改與遠程修改沖突解決方法 2. 未跟蹤文件與遠程文件沖突解決方法 3. 子模塊權限問題解決方法 二、總結 在日常開發中&#xff0c;使用 Git 進行團隊協作和代碼管理時&#xff0c;經常會遇到拉取代碼&#xff08;git…

深度學習、圖像算法學習記錄

深度學習加速 綜述文檔&#xff1a; https://chenzomi12.github.io/02Hardware01Foundation/02ArchSlim.html winograd: https://zhuanlan.zhihu.com/p/260109670 ncnn 1.修改模型結構&#xff0c;優化模型內存訪問次數&#xff0c;加速。 VGG 和 InceptionNet &#xff1a; …

Java中的Exception和Error有什么區別?還有更多擴展

概念 在Java中&#xff0c;Exception和Error都是Throwable的子類&#xff0c;用于處理程序中的錯誤和異常情況。 然而&#xff0c;它們在用途和處理方式上有顯著的不同&#xff1a; Exception&#xff1a; 用于表示程序在正常運行過程中可能出現的錯誤&#xff0c;如文件未找…

文章記單詞 | 第26篇(六級)

一&#xff0c;單詞釋義 actor&#xff1a;名詞&#xff0c;演員mask&#xff1a;名詞&#xff0c;面具&#xff1b;口罩&#xff1b;遮蓋物&#xff1b;動詞&#xff0c;掩飾&#xff1b;戴面具&#xff1b;遮蓋construct&#xff1a;動詞&#xff0c;建造&#xff1b;構造&a…

LeetCode算法題(Go語言實現)_38

題目 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。 一、代碼實現 type TreeNode struct {Val intLeft *TreeNodeRight *TreeNode }func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {if root nil || root p || root q {return root}left : lowes…