【數據結構】排序算法:歸并與堆

歸并排序:分治策略的經典實現

算法原理

歸并排序采用分治法策略,包含三個關鍵步驟:

  1. 分解:遞歸地將數組分成兩半

  2. 解決:對子數組進行排序

  3. 合并:將兩個有序子數組合并為一個有序數組

C語言實現

#include <stdio.h>
#include <stdlib.h>// 合并兩個有序子數組
void merge(int arr[], int left, int mid, int right) {int i, j, k;int n1 = mid - left + 1;int n2 = right - mid;// 創建臨時數組int *L = (int*)malloc(n1 * sizeof(int));int *R = (int*)malloc(n2 * sizeof(int));// 拷貝數據到臨時數組for (i = 0; i < n1; i++)L[i] = arr[left + i];for (j = 0; j < n2; j++)R[j] = arr[mid + 1 + j];// 合并臨時數組i = 0; j = 0; k = left;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];i++;k++;}while (j < n2) {arr[k] = R[j];j++;k++;}free(L);free(R);
}// 歸并排序主函數
void mergeSort(int arr[], int left, int right) {if (left < right) {int mid = left + (right - left) / 2;mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);merge(arr, left, mid, right);}
}

性能分析

  • 時間復雜度:O(n log n)(所有情況)

  • 空間復雜度:O(n)(需要臨時數組)

  • 穩定性:穩定排序(保持相等元素順序)

優化方向

  1. 小數組優化:當子數組較小時(如n<15)改用插入排序

  2. 原地歸并:減少空間使用但增加時間復雜度

  3. 并行化:利用多線程處理獨立子問題

堆排序:基于完全二叉樹的高效排序

算法原理

堆排序利用堆數據結構的特性:

  1. 建堆:將無序數組構建為最大堆

  2. 排序:反復取出堆頂元素(最大值)并調整堆

C語言實現

#include <stdio.h>// 調整堆
void heapify(int arr[], int n, int i) {int largest = i;        // 初始化最大元素為根int left = 2 * i + 1;   // 左子節點int right = 2 * i + 2;  // 右子節點// 如果左子節點大于根if (left < n && arr[left] > arr[largest])largest = left;// 如果右子節點大于當前最大值if (right < n && arr[right] > arr[largest])largest = right;// 如果最大值不是根節點if (largest != i) {// 交換int temp = arr[i];arr[i] = arr[largest];arr[largest] = temp;// 遞歸調整受影響的子堆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--) {// 將當前根移動到數組末尾int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 在減小的堆上調用heapifyheapify(arr, i, 0);}
}

性能分析

  • 時間復雜度:O(n log n)(所有情況)

  • 空間復雜度:O(1)(原地排序)

  • 穩定性:不穩定排序(可能改變相等元素順序)

優化方向

  1. 堆化優化:減少不必要的比較操作

  2. 多叉堆:使用d叉堆減少樹高度

  3. 并行建堆:利用多線程加速建堆過程

算法對比與選擇指南

特性歸并排序堆排序
時間復雜度O(n log n)O(n log n)
空間復雜度O(n)O(1)
穩定性穩定不穩定
適用場景大數據量、外部排序內存受限環境
最佳用途需要穩定結果時優先級隊列實現

實際應用建議

  1. 選擇歸并排序

    • 需要穩定排序結果

    • 處理大數據集(特別是外部排序)

    • 內存充足的情況

  2. 選擇堆排序

    • 內存受限環境

    • 需要原地排序

    • 實現優先級隊列

  3. 其他考慮

    • 小規模數據(n<100)可考慮簡單排序(如插入排序)

    • 現代CPU架構下,歸并排序的緩存友好性可能帶來實際性能優勢

總結

歸并排序和堆排序都是基于O(n log n)復雜度排序算法,各有其特點和適用場景。

歸并排序作為分治策略的經典實現,優勢在于穩定性、可預測的性能以及適用于外部排序的特點。它的遞歸實現簡潔優雅,是理解分治思想的絕佳案例。在實際應用中,歸并排序是處理大規模數據、特別是無法全部裝入內存時的首選算法。

堆排序則充分利用了完全二叉樹的性質,實現了原地排序,空間效率極高。它不僅是一種排序算法,更重要的是其堆數據結構在優先級隊列等場景中有廣泛應用。堆排序特別適合內存受限的環境,或者需要同時維護優先級隊列功能的場景。

在實際開發中,選擇排序算法需要綜合考慮數據結構特征、穩定性要求、內存限制等多方面因素。現代標準庫通常會在不同場景下選擇最適合的排序算法,甚至采用混合策略以獲得最佳性能。

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

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

相關文章

機器學習-CatBoost

參考書籍&#xff1a;《機器學習-公式推導和代碼實現》 官方文檔提供的原生接口代碼參考書籍的P187&#xff5e;P188 簡介 全稱是Categorical Boosting&#xff0c;由俄羅斯搜索引擎巨頭Yandex于2017年提出。突出的優勢是在于可以高效地處理數據中的類別特征 ML中對類別特征…

MPLS 多協議標簽交換

前言&#xff1a; 多協議標簽交換MPLS&#xff08;Multiprotocol Label Switching&#xff09;是一種IP&#xff08;Internet Protocol&#xff09;骨干網技術。MPLS在無連接的IP網絡上引入面向連接的標簽交換概念&#xff0c;將第三層路由技術和第二層交換技術相結合&#xf…

CTF Web PHP弱類型比較與布爾值判斷

題目源碼與注釋 <?php show_source("index.php"); // 顯示自身源碼&#xff0c;方便分析 include("flag.php"); // 包含flag變量 $a $_GET[a]; // 獲取GET參數a&#xff0c;抑制報錯// 關鍵判斷 if($a 0 and $a){echo $flag; …

AntV G6動態連線

完整代碼如下 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AntV G6 動態連線</titl…

puppeteerSharp html轉pdf

部屬到linux 上報錯&#xff1a; Failed to launch browser! /wwwroots/xxx/Chrome/Linux-138.0.7204.92/chrome-linux64/chrome: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory 問題服務包缺少依賴&…

springBoot接口層時間參數JSON序列化問題,兼容處理

背景&#xff1a;解決前端傳入時間參數格式不固定場景&#xff0c;避免接收參數報錯時間格式不能序列化。一、概述在 Java 后端開發中&#xff0c;處理 JSON 數據時&#xff0c;經常需要對日期時間字段進行反序列化。Java 中常用的日期時間類型是 java.time.LocalDateTime&…

List、Set、Map三者之間的關系

1、數據結構與核心特性接口數據結構順序性唯一性鍵值對null 元素List動態數組/鏈表有序&#xff08;插入順序&#xff09;允許重復否允許多個 nullSet哈希表 / 紅黑樹無序&#xff08;HashSet&#xff09;有序&#xff08;LinkedHashSet/TreeSet&#xff09;不允許重復否僅 Has…

進程控制----進程終止

一、進程終止的核心場景正常終止&#xff08;代碼完整運行完畢&#xff09;成功&#xff1a;進程執行到main函數結束或調用exit()&#xff0c;返回退出碼 0&#xff08;約定為執行成功&#xff09;。失敗&#xff1a;代碼執行完畢但結果異常&#xff0c;返回非零退出碼&#xf…

Milvus docker-compose 部署

文章目錄 前言Milvus docker-compose 部署1. 下載2. 修改配置3. 啟動4. 測試 前言 如果您覺得有用的話&#xff0c;記得給博主點個贊&#xff0c;評論&#xff0c;收藏一鍵三連啊&#xff0c;寫作不易啊^ _ ^。 ??而且聽說點贊的人每天的運氣都不會太差&#xff0c;實在白嫖的…

EveryThing搜索具體路徑下文件中的內容

1.打開EveryThing 2.點擊搜索&#xff0c;選擇高級搜索 3.選擇需要搜索的文件的路徑以及文件中需要包含的內容 4.之后就可以搜索到對應的目標文件

【算法】寬度優先遍歷BFS

二叉樹的寬搜 429、N叉樹的層序遍歷 題解 BFS核心思想 二叉樹的寬搜一般都是借助隊列來實現的&#xff0c;實現的原理為首先將根節點進行放入隊列中&#xff0c;然后將根節點進行彈出的時候&#xff0c;將這個節點的孩子節點進行放入隊列中&#xff0c;然后繼續彈出隊頭的元…

【STM32】通用定時器基本原理

STM32 通用定時器基本原理&#xff08;基于 STM32F1&#xff09;參考資料&#xff1a;STM32F1xx官方資料&#xff1a;《STM32中文參考手冊V10》-第14章通用定時器STM32 定時器分類 STM32F103 系列共有三類定時器&#xff1a;&#x1f50e; 通用定時器&#xff08;TIM2~TIM5&…

【Go語言-Day 14】深入解析 map:創建、增刪改查與“鍵是否存在”的奧秘

Langchain系列文章目錄 01-玩轉LangChain&#xff1a;從模型調用到Prompt模板與輸出解析的完整指南 02-玩轉 LangChain Memory 模塊&#xff1a;四種記憶類型詳解及應用場景全覆蓋 03-全面掌握 LangChain&#xff1a;從核心鏈條構建到動態任務分配的實戰指南 04-玩轉 LangChai…

Vue腳手架搭建項目+基礎知識

1. 使用腳手架創建項目1.1 準備工作winR&#xff0c;在彈出的數據框中輸入cmd&#xff0c;數據命令查看node以及npm版本 下載vue cli1.2 創建項目1.2.1 創建一個英文目錄文件夾&#xff0c;cmd打開命令命令提示符1.2.2 vue ui命令打開控制臺1.2.3 創建項目創建成功1.3 項目結構…

微信小程序下單頁—地址列表頁—新增地址頁 頁面交互

新增地址流程&#xff1a; 下單頁 → 地址列表頁 (1次跳轉)地址列表頁 → 新增地址頁 (1次跳轉)保存地址 → 返回地址列表頁 (1次返回&#xff0c;自動刷新列表) 選擇地址流程&#xff1a; 地址列表頁 → 選中地址 → 返回下單頁 (1次返回) 更換地址&#xff1a; 下單頁 → 地址…

JVM與JMM

為了更清晰地對比JVM和JMM&#xff0c;我們可以采用表格形式&#xff0c;從定義、功能、結構、與多線程關系等方面進行詳細比較&#xff1a; 對比項JVM&#xff08;Java Virtual Machine&#xff09;JMM&#xff08;Java Memory Model&#xff09;定義一種虛構的計算機&#x…

【Docker基礎】Docker數據卷管理:docker volume rm及其參數詳解

目錄 1 引言&#xff1a;Docker Volume 的生命周期管理 2 docker volume rm命令基礎 2.1 命令作用 2.2 命令語法 3 參數深度解析 3.1 基礎參數表 3.2 高級參數詳解 3.2.1 --force&#xff08;-f&#xff09; 4 Volume刪除前置條件 4.1 可刪除狀態判斷 4.2 常見報錯處…

嵌入式系統內核鏡像相關(十)

文章目錄 前言一、點亮多個led燈的基礎實驗以及其中的問題1.1 基礎流程1.1.1 alinx教程的問題1.1.1.1 驅動程序中的亮/滅邏輯修改&#xff01;1.1.1.1.1 邏輯錯誤的修改1.1.1.1.2 多燈亮/滅 1.1.1.2 驅動程序中引腳的問題以及與裸機開發的區別&#xff08;重要&#xff09;1.1.…

Word和Excel批量轉PDF新方法,操作簡單

PDF是一種跨平臺的文檔格式&#xff0c;無論在任何設備上查看&#xff0c;其排版、字體和圖像都不會發生變化。這確保了文檔的一致性&#xff0c;避免了由于不同軟件版本或操作系統引起的顯示問題。這款小巧的工具大小不到2MB&#xff0c;使用起來異常簡單。只需要把需要轉換的…

AI搜索 MCP最佳實踐

背景 那些 LLM 不知道的事 嘗試直接詢問LLM“今天天氣如何”時&#xff0c;會發現LLM無法回答——它既不知道“今天”是哪天&#xff0c;也無法獲取地理位置信息。這揭示了LLM的局限&#xff1a;缺乏與外部工具和實時數據的交互能力。 為解決這一問題&#xff0c;MCP&#x…