深入理解C語言數據結構之快速排序三路劃分

在數據結構和算法的世界里,排序算法是基石一般的存在。快速排序作為一種高效的排序算法,以其平均情況下的優秀時間復雜度而被廣泛應用。今天,讓我們深入探討快速排序的一種變體——三路劃分的快速排序,看看它是如何在C語言中施展魔法的。
?


快速排序基礎回顧
?


在介紹三路劃分快速排序之前,先來簡單回顧下傳統快速排序。傳統快速排序的核心思想是分治法,選擇一個基準元素,通過一趟排序將待排序列分割成兩部分,其中一部分的元素都比基準元素小,另一部分的元素都比基準元素大,然后分別對這兩部分遞歸地進行排序。
?
傳統快速排序代碼示例
?

c#include <stdio.h>// 交換兩個整數
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 劃分函數
int partition(int arr[], int low, int high) {int pivot = arr[high];int i = (low - 1);for (int j = low; j <= high - 1; 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);}
}// 打印數組
void printArray(int arr[], int size) {for (int i = 0; i < size; i++)printf("%d ", arr[i]);printf("\n");
}


?
?
可以使用以下方式調用這個函數:
?

cint main() {int arr[] = {10, 7, 8, 9, 1, 5};int n = sizeof(arr) / sizeof(arr[0]);printf("初始數組: ");printArray(arr, n);quickSort(arr, 0, n - 1);printf("排序后的數組: ");printArray(arr, n);return 0;
}


?
?
在傳統快速排序中,每次劃分只能確定一個基準元素的最終位置,當數組中存在大量重復元素時,這種方式的效率會受到影響。而三路劃分快速排序就是為了解決這個問題而誕生的。
?


三路劃分快速排序原理
?


三路劃分快速排序,也稱為荷蘭國旗問題的解法(因為它和將紅、白、藍三種顏色的球按順序排列的問題類似)。在三路劃分中,數組被分成三個部分:小于基準元素的部分、等于基準元素的部分和大于基準元素的部分。
?
具體步驟
?
1.?初始化指針:設置三個指針,?lt?(less than)初始指向數組起始位置,?gt?(greater than)初始指向數組末尾位置,?i??初始也指向數組起始位置。
?
2.?遍歷數組:通過 ?i??指針遍歷數組:
?
- 如果 ?arr[i]??小于基準元素,交換 ?arr[i]??和 ?arr[lt]?,然后 ?i??和 ?lt??都向右移動一位。
?
- 如果 ?arr[i]??等于基準元素,?i??直接向右移動一位。
?
- 如果 ?arr[i]??大于基準元素,交換 ?arr[i]??和 ?arr[gt]?,然后 ?gt??向左移動一位,但 ?i??不移動,因為交換過來的 ?arr[gt]??還未比較。
?
3.?遞歸排序:遞歸地對小于基準和大于基準的兩部分進行排序。
?
三路劃分快速排序代碼實現
?

c#include <stdio.h>// 交換兩個整數
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 三路劃分函數
void partition(int arr[], int low, int high, int *lt, int *gt) {int pivot = arr[low];*lt = low;*gt = high;int i = low;while (i <= *gt) {if (arr[i] < pivot) {swap(&arr[*lt], &arr[i]);(*lt)++;i++;} else if (arr[i] > pivot) {swap(&arr[i], &arr[*gt]);(*gt)--;} else {i++;}}
}// 三路劃分快速排序函數
void quickSort3Way(int arr[], int low, int high) {if (low < high) {int lt, gt;partition(arr, low, high, &lt, &gt);quickSort3Way(arr, low, lt - 1);quickSort3Way(arr, gt + 1, high);}
}// 打印數組
void printArray(int arr[], int size) {for (int i = 0; i < size; i++)printf("%d ", arr[i]);printf("\n");
}


?
可以使用以下方式調用這個函數:
?

cint main() {int arr[] = {10, 7, 8, 9, 1, 5, 5, 5};int n = sizeof(arr) / sizeof(arr[0]);printf("初始數組: ");printArray(arr, n);quickSort3Way(arr, 0, n - 1);printf("排序后的數組: ");printArray(arr, n);return 0;
}


注意點和要點
?
1.?基準元素的選擇:在上述代碼中,我們選擇數組的第一個元素作為基準元素。在實際應用中,也可以隨機選擇基準元素,以避免最壞情況的發生。
?
2.?邊界條件:在劃分過程中,要注意指針的移動和邊界條件的判斷,確保不會越界。
?
3.?遞歸終止條件:遞歸調用時,要確保遞歸有終止條件,即 ?low < high?,否則會導致棧溢出。
?
4.?性能優勢:三路劃分快速排序在處理包含大量重復元素的數組時,性能明顯優于傳統快速排序,因為它避免了對重復元素的重復排序。
?


總結
?


三路劃分快速排序是一種在特定情況下表現出色的排序算法,通過巧妙的指針操作和劃分策略,它有效地提高了對包含重復元素數組的排序效率。希望通過這篇博客,你對三路劃分快速排序有了更深入的理解,并且能夠在實際應用中靈活運用。在算法的世界里,每一次的探索都像是一場奇妙的冒險,愿你在這個充滿挑戰和驚喜的領域中不斷前行。

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

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

相關文章

Java實現后量子密碼(PQC)與國密算法(SM4)混合加密

以下是使用Java實現一種后量子密碼(PQC)與國密算法(SM4)混合加密的示例方案。該方案結合了后量子密碼的抗量子特性與國密算法的國產化合規要求,適合需要雙重安全保障的場景。 一 . 方案驗證 1.代碼截圖 2.運行測試 二 . 方案設計 密鑰交換:使用后量子密碼(如Kyber)生…

【SQL Server數據庫備份詳細教程】

&#x1f3a5;博主&#xff1a;程序員不想YY啊 &#x1f4ab;CSDN優質創作者&#xff0c;CSDN實力新星&#xff0c;CSDN博客專家 &#x1f917;點贊&#x1f388;收藏?再看&#x1f4ab;養成習慣 ?希望本文對您有所裨益&#xff0c;如有不足之處&#xff0c;歡迎在評論區提出…

SpringBoot古典舞在線交流平臺設計與實現

隨著古典舞文化的普及&#xff0c;越來越多的人希望通過線上平臺交流學習。幽絡源作為一站式綜合平臺&#xff0c;致力于為用戶提供免費源碼、技術教程及網絡兼職資源。本文將詳細介紹基于SpringBoot的古典舞在線交流平臺的設計與實現&#xff0c;幫助開發者快速搭建一個功能完…

關于絕對時間、人類時間、本地時間、時區時間的對比分析,結合編程場景(如Java)進行說明

以下是關于絕對時間、人類時間、本地時間、時區時間的對比分析&#xff0c;結合編程場景&#xff08;如Java&#xff09;進行說明&#xff1a; 1. 定義與核心區別 (1) 絕對時間&#xff08;Absolute Time&#xff09; 定義&#xff1a;不受時區影響&#xff0c;以固定時間起點…

go語言中的strings庫

strings庫 func EqualFold func EqualFold(s, t string) bool判斷兩個utf-8編碼字符串&#xff08;將unicode大寫、小寫、標題三種格式字符視為相同&#xff09;是否相同。 func main() {fmt.Println(strings.EqualFold("hello", "hello")) //truefmt.…

Git沖突解決

目錄 一、Git沖突產生的原因二、解決Git沖突的步驟1. 發現沖突2. 查看沖突文件3. 手動解決沖突4. 提交解決后的代碼5. 完成合并 三、預防Git沖突的小技巧四、總結 在團隊協作開發中&#xff0c;Git沖突是常見的問題。當多個開發者同時修改了同一個文件的不同部分&#xff0c;然…

Spring AOP + RocketMQ 實現企業級操作日志異步采集(實戰全流程)

Spring AOP + RocketMQ 實現企業級操作日志異步采集(實戰全流程) ?? 項目背景 在企業級微服務架構中,記錄操作日志是一項剛需。傳統方式常使用數據庫直接寫入或通過 Feign 調用日志微服務,但這樣存在耦合高、主流程阻塞、擴展性差等問題。 為此,我們將使用: Spring …

Git Flow 分支管理策略

優勢 清晰的分支結構&#xff1a;每個分支都有明確的用途&#xff0c;便于團隊協作。 穩定的 master 分支&#xff1a;生產環境代碼始終穩定。 靈活的發布管理&#xff1a;通過發布分支和熱修復分支&#xff0c;可以靈活管理版本發布和緊急修復。 主要分支 master 分支 代表…

Altium Designer數模電學習筆記

模電 電容 **退耦&#xff1a;**利用通交阻直&#xff0c;將看似直流的信號中的交流成分濾除 &#xff08;一般用在給MPU供電&#xff0c;盡量小一些&#xff0c;10nf~100nf~1uf以下&#xff09; **濾波&#xff1a;**也可以理解為給電容充電&#xff0c;讓電容在電平為低時…

光譜儀與光譜相機的核心區別與協同應用

一、核心功能與數據維度 ?光譜儀? ?功能定位?&#xff1a;專注單點或線狀區域的光譜分析&#xff0c;通過色散元件&#xff08;光柵/棱鏡&#xff09;分離波長&#xff0c;生成一維或二維光譜曲線&#xff0c;用于量化光強、吸收率等參數?。 ?數據維度?&#xff1a;輸…

Pytorch中layernorm實現詳解

平時我們在編寫神經網絡時&#xff0c;經常會用到layernorm這個函數來加快網絡的收斂速度。那layernorm到底在哪個維度上進行歸一化的呢&#xff1f; 一、問題描述 首先借用知乎上的一張圖&#xff0c;原文寫的也非常好&#xff0c;大家有空可以去閱讀一下&#xff0c;鏈接放…

linux--時區查看和修改

查看當前時間和時區: 打開終端&#xff0c;輸入以下命令查看當前的日期和時間設置&#xff1a; timedatectl修改時區: 使用 timedatectl 命令來修改時區&#xff1a; sudo timedatectl set-timezone <時區>例如&#xff0c;設置時區為北京時間&#xff08;中國標準時間&a…

在windows下安裝windows+Ubuntu16.04雙系統(上)

這篇文章的內容主要來源于這篇文章&#xff0c;給文章很詳細的介紹了如何從windows下安裝windowsubuntu16.04雙系統。我剛開始裝雙系統都是參照這個方法&#xff0c;該作者前后更新了兩個版本&#xff0c;在這里對其稍微進行整理一下。 一、準備&#xff1a;&#xff08;這里推…

如何獲取thinkphp的所有發行版本

是的&#xff0c;你只需要一行代碼 composer show topthink/think --all 然后做了一個小實驗&#xff0c;神奇的事情發生了。是我眼睛花了嗎&#xff1f; 命令也能模糊查詢了嗎&#xff1f;tp6也太。。。。

算法模型從入門到起飛系列——遞歸(探索自我重復的奇妙之旅)

文章目錄 前言一、遞歸本質1.1 遞歸的要素1.2 遞歸特點 二、遞歸&迭代2.1 遞歸&迭代比較2.2 遞歸&迭代如何實現相同功能2.2.1 遞歸實現2.2.2 迭代實現2.2.3 性能對比 三、優雅的遞歸理解3.1 階乘計算分解3.2 [DFS](https://blog.csdn.net/qq_38315952/article/deta…

Android 系統進程啟動Activity方法說明

前面文章Android Activity的啟動器ActivityStarter入口說到Activity的恢復執行是由 mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch)來實現的&#xff0c;下面就看下它的實現。 RootWindowContainer類的…

PostgreSQL_安裝

目錄 前置&#xff1a; 安裝過程&#xff1a; 1 下載軟件 2 創建安裝文件夾和放置數據的文件夾 3 雙擊安裝 4 連接服務 前置&#xff1a; PostgreSQL 15 windows 10 專業版 安裝過程&#xff1a; 1 下載軟件 PostgreSQL: Downloads 大小326MB 2 創建安裝文件夾和放…

docker desktop 集成WSL Ubuntu22.04

Windows docker desktop 設置WSL ubuntu 22.04啟用與其他發行版的集成 Windows docker desktop 安裝參考 wsl ubuntu 22.04 查看我宿主機的docker desktop 容器全部的信息 wsl -d Ubuntu-22.04 -u root

從國家能源到浙江交通投資,全息技術在能源交通領域的創新應用

一、3D全息技術行業應用參數及設計制作要求 全息投影 全息投影技術通過激光器、全息片等設備&#xff0c;將物體的三維信息記錄下來&#xff0c;并在特定條件下再現。應用參數包括投影距離、投影面積、投影亮度等。設計制作要求&#xff1a;高清晰度、高亮度、低噪音、穩定性好…

新能源汽車充換站如何實現光儲充一體化管理?

長三角某換電站光伏板曬到發燙&#xff0c;卻因電網限電被迫切機&#xff1b;北京五環充電站每月多繳6萬超容費&#xff1b;深圳物流車充電高峰排隊3小時...當95%的充換站深陷“用不起綠電、扛不住擴容、算不清碳賬”困局&#xff0c;安科瑞用一組真實數據撕開行業潛規則&#…