算法基礎之八大排序

文章目錄

    • 概要
    • 1. 冒泡排序(Bubble Sort)
    • 2. 選擇排序(Selection Sort)
    • 3. 插入排序(Insertion Sort)
    • 4. 希爾排序(Shell Sort)
    • 5. 歸并排序(Merge Sort)
    • 6. 快速排序(Quick Sort)
    • 7. 堆排序(Heap Sort)
    • 8. 計數排序(Counting Sort)
  • 小結

概要

排序算法是編程中最基礎也是最重要的算法之一。通過學習和理解不同的排序算法,我們可以在實際開發中選擇合適的算法來解決問題。本文將介紹八大常用排序算法,并分別用 Python、C++ 和 Java 三種語言實現。


時間復雜度

1. 冒泡排序(Bubble Sort)

算法描述: 冒泡排序是一種簡單的排序算法,通過不斷交換相鄰元素,使得較大的元素“浮”到數組的末尾。

時間復雜度

  • 最佳情況:O(n)
  • 平均情況:O(n2)
  • 最壞情況:O(n2)

空間復雜度: O(1)
穩定性: 穩定

實現步驟

  1. 比較相鄰元素,前大則交換

  2. 對每一對相鄰元素重復操作

  3. 每次遍歷后范圍縮小1

  4. 重復直到無交換發生

代碼實現

python版本

def bubble_sort(arr):n = len(arr)for i in range(n-1):for j in range(n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]return arr

C++版本

void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {// Swap elementsint temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}
}

Java版本

public class BubbleSort {public static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n-1; i++) {for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {// Swap elementsint temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}
}

2. 選擇排序(Selection Sort)

算法描述: 選擇排序通過分為有序區和無序區,逐步從無序區中找到最小元素,放到有序區的末尾。

時間復雜度:

  • 最佳情況:O(n2)
  • 平均情況:O(n2)
  • 最壞情況:O(n2)

空間復雜度: O(1)

穩定性: 不穩定

代碼實現
python版本

# Python
def bubble_sort(arr):n = len(arr)for i in range(n-1):swapped = Falsefor j in range(n-1-i):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]swapped = Trueif not swapped:breakreturn arr

C++版本

// C++
void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; ++i) {bool swapped = false;for (int j = 0; j < n-1-i; ++j) {if (arr[j] > arr[j+1]) {swap(arr[j], arr[j+1]);swapped = true;}}if (!swapped) break;}
}

Java版本

// Java
public static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n-1; i++) {boolean swapped = false;for (int j = 0; j < n-1-i; j++) {if (arr[j] > arr[j+1]) {int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;swapped = true;}}if (!swapped) break;}
}

3. 插入排序(Insertion Sort)

算法思想: 將未排序元素逐個插入已排序序列的合適位置

時間復雜度:

  • 平均:O(n2)

  • 最壞:O(n2)

  • 最好:O(n)

穩定性: 穩定

python版本

# Python
def insertion_sort(arr):for i in range(1, len(arr)):key = arr[i]j = i-1while j >=0 and key < arr[j] :arr[j+1] = arr[j]j -= 1arr[j+1] = keyreturn arr

C++版本

// C++
void insertionSort(int arr[], int n) {for (int i = 1; i < n; ++i) {int key = arr[i];int j = i-1;while (j >= 0 && arr[j] > key) {arr[j+1] = arr[j];j--;}arr[j+1] = key;}
}

Java版本

// Java
public static void insertionSort(int[] arr) {for (int i = 1; i < arr.length; ++i) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j+1] = arr[j];j--;}arr[j+1] = key;}
}

4. 希爾排序(Shell Sort)

算法思想: 改進的插入排序,通過間隔分組進行預處理
時間復雜度: O(n log n) ~ O(n2)
穩定性: 不穩定

python版本

# Python
def shell_sort(arr):n = len(arr)gap = n//2while gap > 0:for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j-gap] > temp:arr[j] = arr[j-gap]j -= gaparr[j] = tempgap //= 2return arr

C++版本

// C++
void shellSort(int arr[], int n) {for (int gap = n/2; gap > 0; gap /= 2) {for (int i = gap; i < n; ++i) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)arr[j] = arr[j - gap];arr[j] = temp;}}
}

Java版本

// Java
public static void shellSort(int[] arr) {int n = arr.length;for (int gap = n/2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)arr[j] = arr[j - gap];arr[j] = temp;}}
}

5. 歸并排序(Merge Sort)

算法思想: 分治法,遞歸拆分后合并有序子序列
時間復雜度: O(n log n)
穩定性: 穩定

python版本

# Python
def merge_sort(arr):if len(arr) > 1:mid = len(arr)//2L = arr[:mid]R = arr[mid:]merge_sort(L)merge_sort(R)i = j = k = 0while i < len(L) and j < len(R):if L[i] < R[j]:arr[k] = L[i]i += 1else:arr[k] = R[j]j += 1k += 1while i < len(L):arr[k] = L[i]i += 1k += 1while j < len(R):arr[k] = R[j]j += 1k += 1return arr

C++版本:

// C++
void merge(int arr[], int l, int m, int r) {int n1 = m - l + 1;int n2 = r - m;int L[n1], R[n2];for (int i = 0; i < n1; i++)L[i] = arr[l + i];for (int j = 0; j < n2; j++)R[j] = arr[m + 1 + j];int i = 0, j = 0, k = l;while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k] = L[i];i++;} else {arr[k] = R[j];j++;}k++;}while (i < n1) arr[k++] = L[i++];while (j < n2) arr[k++] = R[j++];
}void mergeSort(int arr[], int l, int r) {if (l < r) {int m = l + (r - l)/2;mergeSort(arr, l, m);mergeSort(arr, m+1, r);merge(arr, l, m, r);}
}

Java版本

// Java
public static void mergeSort(int[] arr, int l, int r) {if (l < r) {int m = (l + r) / 2;mergeSort(arr, l, m);mergeSort(arr, m + 1, r);int[] L = Arrays.copyOfRange(arr, l, m + 1);int[] R = Arrays.copyOfRange(arr, m + 1, r + 1);int i = 0, j = 0, k = l;while (i < L.length && j < R.length) {if (L[i] <= R[j]) arr[k++] = L[i++];else arr[k++] = R[j++];}while (i < L.length) arr[k++] = L[i++];while (j < R.length) arr[k++] = R[j++];}
}

6. 快速排序(Quick Sort)

算法思想: 分治法,選取基準元素進行分區排序
時間復雜度:

  • 平均:O(n log n)

  • 最壞:O(n2)

穩定性: 不穩定

python版本

在這里插入代碼片# Python
def quick_sort(arr):if len(arr) <= 1:return arrpivot = 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)

C++版本:

// C++
int partition(int arr[], int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;swap(arr[i], arr[j]);}}swap(arr[i+1], arr[high]);return i+1;
}void quickSort(int arr[], int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi-1);quickSort(arr, pi+1, high);}
}

Java版本

// Java
public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi-1);quickSort(arr, pi+1, high);}
}private static int partition(int[] arr, int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i+1];arr[i+1] = arr[high];arr[high] = temp;return i+1;
}

7. 堆排序(Heap Sort)

算法思想: 利用堆數據結構進行選擇排序
時間復雜度: O(n log n)
穩定性: 不穩定

python版本

# Python
def heapify(arr, n, i):largest = il = 2 * i + 1r = 2 * i + 2if l < n and arr[l] > arr[largest]:largest = lif r < n and arr[r] > arr[largest]:largest = rif largest != i:arr[i], arr[largest] = arr[largest], arr[i]heapify(arr, n, largest)def heap_sort(arr):n = len(arr)for i in range(n//2-1, -1, -1):heapify(arr, n, i)for i in range(n-1, 0, -1):arr[i], arr[0] = arr[0], arr[i]heapify(arr, i, 0)return arr

C++版本:

// C++
void heapify(int arr[], int n, int i) {int largest = i;int l = 2*i + 1;int r = 2*i + 2;if (l < n && arr[l] > arr[largest])largest = l;if (r < n && arr[r] > arr[largest])largest = r;if (largest != i) {swap(arr[i], arr[largest]);heapify(arr, n, largest);}
}void heapSort(int arr[], int n) {for (int i = n/2 - 1; i >= 0; i--)heapify(arr, n, i);for (int i = n-1; i > 0; i--) {swap(arr[0], arr[i]);heapify(arr, i, 0);}
}

Java版本

// Java
public static void heapSort(int[] arr) {int n = arr.length;for (int i = n/2 - 1; i >= 0; i--)heapify(arr, n, i);for (int i = n-1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;heapify(arr, i, 0);}
}private static void heapify(int[] arr, int n, int i) {int largest = i;int l = 2*i + 1;int r = 2*i + 2;if (l < n && arr[l] > arr[largest]) largest = l;if (r < n && arr[r] > arr[largest]) largest = r;if (largest != i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;heapify(arr, n, largest);}
}

8. 計數排序(Counting Sort)

適用場景: 整數排序且值范圍不大
時間復雜度: O(n + k)
穩定性: 穩定

python版本

# Python
def counting_sort(arr):max_val = max(arr)count = [0] * (max_val + 1)for num in arr:count[num] += 1idx = 0for i in range(len(count)):while count[i] > 0:arr[idx] = iidx += 1count[i] -= 1return arr

C++版本:

// C++
void countingSort(int arr[], int n) {int maxVal = *max_element(arr, arr + n);int count[maxVal + 1] = {0};for (int i = 0; i < n; i++)count[arr[i]]++;int idx = 0;for (int i = 0; i <= maxVal; i++) {while (count[i]-- > 0) {arr[idx++] = i;}}
}

Java版本

// Java
public static void countingSort(int[] arr) {int maxVal = Arrays.stream(arr).max().getAsInt();int[] count = new int[maxVal + 1];for (int num : arr) count[num]++;int idx = 0;for (int i = 0; i <= maxVal; i++) {while (count[i]-- > 0) {arr[idx++] = i;}}
}

小結

排序算法平均時間復雜度最壞時間復雜度空間復雜度穩定性
冒泡排序O(n2)O(n2)O(1)穩定
選擇排序O(n2)O(n2)O(1)不穩定
插入排序O(n2)O(n2)O(1)穩定
希爾排序O(n log n)O(n2)O(1)不穩定
歸并排序O(n log n)O(n log n)O(n)穩定
快速排序O(n log n)O(n2)O(log n)不穩定
堆排序O(n log n)O(n log n)O(1)不穩定
計數排序O(n + k)O(n + k)O(k)穩定

注:k為計數排序的值域范圍

應用場景建議:

  • 小規模數據:插入排序

  • 通用高效:快速排序

  • 內存敏感:堆排序

  • 穩定需求:歸并排序

  • 整數排序:計數排序

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

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

相關文章

html 列動態布局

樣式說明&#xff1a; /* 列動態布局&#xff0c;列之間以空格填充 */ li {display: flex;/* flex-direction: column; */justify-content: space-between; }

(python)如何看自己安裝的包的版本

linux pip list | grep "numpy\|scipy\|tensorflow\|keras"windows環境下 pip list | findstr "numpy scipy tensorflow keras"輸出 numpy 1.13.1 scipy 0.19.1 tensorflow-cpu 2.4.0 tensorflow-estimator 2.4.0 tensorflow-gpu 2.4.0

從O(k*n)到O(1):如何用哈希表終結多層if判斷的性能困局

【前言】 ??本文將以哈希表重構實戰為核心&#xff0c;完整展示如何將傳統條件匹配邏輯(上千層if-else判斷)轉化為O(1)的哈希表高效實現。通過指紋驗證場景的代碼級解剖&#xff0c;您將深入理解&#xff1a; ??1.哈希函數設計如何規避沖突陷阱 ??2.鏈式尋址法的工程實現…

離線統信系統的python第三方庫批量安裝流程

一、關于UOS本機 操作系統&#xff1a;UOS&#xff08;基于Debian的Linux發行版&#xff09; CPU&#xff1a;海光x86 二、具體步驟 1、在聯網的電腦上用控制臺的pip命令批量下載指定版本的第三方庫 方法A cd <目標位置的絕對路徑> pip download -d . --platform many…

第 26 場 藍橋入門賽

3.電子舞龍【算法賽】 - 藍橋云課 問題描述 話說這年頭&#xff0c;連舞龍都得電子化&#xff01;這不&#xff0c;藍橋村的老程序員王大爺突發奇想&#xff0c;用LED燈帶和一堆傳感器鼓搗出了一條“電子舞龍”&#xff0c;它能根據程序指令在村里的廣場上“翩翩起舞”。 廣…

0012—數組

存取一組數據&#xff0c;使用數組。 數組是一組相同類型元素的集合。 要存儲1-10的數字&#xff0c;怎么存儲&#xff1f; C語言中給了數組的定義&#xff1a;一組相同類型元素的集合。 創建一個空間創建一組數&#xff1a; 一、數組的定義 int arr[10] {1,2,3,4,5,6,7,8,…

詳細教程 | 如何使用DolphinScheduler調度Flink實時任務

Apache DolphinScheduler 非常適用于實時數據處理場景&#xff0c;尤其是與 Apache Flink 的集成。DolphinScheduler 提供了豐富的功能&#xff0c;包括任務依賴管理、動態調度、實時監控和日志管理&#xff0c;能夠有效簡化 Flink 實時任務的管理和部署。通過 DolphinSchedule…

Redis Copilot:基于Redis為AI打造的副駕工具

我們最近發布了Redis Copilot&#xff0c;以幫助開發者更快地使用Redis構建應用。我們的使命是使應用程序快速運行&#xff0c;并簡化構建過程。為此&#xff0c;Redis Copilot作為您的AI助手&#xff0c;能夠讓您更迅速地完成與Redis相關的任務。您今天就可以在Redis Insight中…

了解傳輸層TCP協議

目錄 一、TCP協議段格式 二、TCP原理 1.確認應答 2.超時重傳 3.連接管理 建立連接 斷開連接 4.滑動窗口 5.流量控制 6.擁塞控制 7.延時應答 8.捎帶應答 9.面向字節流 10.TCP異常情況 TCP&#xff0c;即Transmission Control Protocol&#xff0c;傳輸控制協議。人如…

idea 如何使用deepseek 保姆級教程

1.安裝idea插件codegpt 2.注冊deepseek并生成apikey deepseek 開發平臺&#xff1a; DeepSeek??????? 3.在idea進行codegpt配置 打開idea的File->Settings->Tools->CodeGPT->Providers->Custom OpenAI Chat Completions的URL填寫 https://api.deepseek…

面試真題 | 超圖駿科 C++

構造函數的類型及其描述 在C++中,構造函數是用于初始化對象的特殊成員函數。根據用途和參數的不同,可以將構造函數分為以下幾種類型: 默認構造函數(Default Constructor) 描述:沒有參數的構造函數。如果類中沒有定義任何構造函數,編譯器會自動生成一個默認構造函數。但…

華為OD機試E卷 --矩陣擴散--24年OD統一考試(Java JS Python C C++)

文章目錄 題目描述輸入描述輸出描述用例題目解析JS算法源碼Java算法源碼python算法源碼c算法源碼題目描述 存在一個 m n 的 二維數組 ,其成員取值范圍為 0 或 1。 其中值為 1 的成員具備擴散性,每經過 1s,將上下左右值為 0 的成員同化為 1。 二維數組的成員 初始值 都為 0…

系統URL整合系列視頻五(后端技術實現)

視頻 系統URL整合系列視頻五&#xff08;后端技術實現&#xff09; 視頻介紹 &#xff08;全國&#xff09;大型分布式系統Web資源URL整合需求后端技術實現。當今社會各行各業對軟件系統的web資源訪問權限控制越來越嚴格&#xff0c;控制粒度也越來越細。安全級別提高的同時也…

二叉樹理論基礎詳解:從零開始理解數據結構的核心

二叉樹理論基礎詳解&#xff1a;從零開始理解數據結構的核心 在算法與數據結構的學習中&#xff0c;二叉樹是一種非常基礎但又極其重要的數據結構。無論是編程面試還是實際開發&#xff0c;對二叉樹的 理解都是必不可少的技能。本文將從頭開始&#xff0c;系統地介紹二叉樹的基…

Linux之kernel(1)系統基礎理論(1)

Linux之Kernel(1)系統基礎理論(1) Author: Once Day Date: 2025年2月6日 一位熱衷于Linux學習和開發的菜鳥&#xff0c;試圖譜寫一場冒險之旅&#xff0c;也許終點只是一場白日夢… 漫漫長路&#xff0c;有人對你微笑過嘛… 全系列文章可參考專欄: Linux內核知識_Once-Day的…

Deepseek部署的模型參數要求

DeepSeek 模型部署硬件要求 模型名稱參數量顯存需求&#xff08;推理&#xff09;顯存需求&#xff08;微調&#xff09;CPU 配置內存要求硬盤空間適用場景DeepSeek-R1-1.5B1.5B4GB8GB最低 4 核&#xff08;推薦多核&#xff09;8GB3GB低資源設備部署&#xff0c;如樹莓派、舊…

如何解決 javax.xml.crypto.dsig.TransformException: 轉換異常問題?親測有效的解決方法!

1. 問題分析 1.1 異常描述 javax.xml.crypto.dsig.TransformException 是在使用 Java XML 加密和簽名 API 時&#xff0c;發生的一個常見異常。它通常出現在 XML 數字簽名的轉換過程中&#xff0c;可能是由于簽名、加密或驗證過程中發生了錯誤。 1.2 異常場景 該異常通常發…

【讀書筆記·VLSI電路設計方法解密】問題46:什么是bug覆蓋率

在IC設計項目的驗證過程中&#xff0c;功能測試&#xff08;通過使用測試平臺&#xff09;有助于定位設計錯誤或漏洞。這個驗證過程有三個階段&#xff1a;構建和啟動測試平臺、驗證基本測試用例以及驗證邊界情況。 在前兩個階段&#xff0c;漏洞很容易被檢測到&#xff0c;因…

【python】簡單的flask做頁面。一組字母組成的所有單詞。這里的輸入是一組字母,而輸出是所有可能得字母組成的單詞列表

目錄結構如下&#xff1a; . ├── static │ ├── css │ │ └── styles.css │ └── js │ └── scripts.js ├── templates │ ├── base.html │ ├── case_converter.html │ ├── index.html │ └── word_finder.html ├── app.py ├── tree.py…

借助 Cursor 快速實現小程序前端開發

借助 Cursor 快速實現小程序前端開發 在當今快節奏的互聯網時代&#xff0c;小程序因其便捷性、高效性以及無需下載安裝的特點&#xff0c;成為眾多企業和開發者關注的焦點。然而&#xff0c;小程序的開發往往需要耗費大量的時間和精力&#xff0c;尤其是在前端開發階段。幸運…