學習數據結構(16)快速排序

快速排序的基本思想:快速排序是Hoare于1962年提出的一種二叉樹結構的交換排序方法,其基本思想為:任取待排序元素序列中的某元素作為基準值,按照該基準值將待排序集合分割成兩子序列,左子序列中所有元素均小于基準值,右子序列中所有元素均大于基準值,然后左右子序列重復該過程,直到所有元素都排列在相應位置上為止。

1、遞歸版本

遞歸版本實現的主要框架:

void QuickSort(int* arr, int left, int right)
{if(left >= right){return;}int keyi = _QuickSort(arr, left, right);QuickSort(arr, left, keyi - 1);QuickSort(arr, keyi+1, right);
} 
(1)hoare方法

這個函數的作用在于將基準值移到數組正確的位置并返回此處的下標。

left從基準值后一個位置開始移動,當left<=right時進入循環,left循環向前移動找比基準值大的數據,找到跳出循環,left循環向后移動找比基準值小的數據,找到跳出循環,此時若left<=right,交換left和right的數據,right--,left++繼續循環。直到left>right跳出循環,此時right所在的位置就是基準值的正確位置,交換keyi和right的數據,返回right。

int _QuickSort(int* arr, int left, int right)
{int keyi = left;++left;while (left <= right){while (left <= right&&arr[left] < arr[keyi]){++left;}while (left <= right && arr[right] > arr[keyi]){--right;}if (left <= right){swap(&arr[right--], &arr[left++]);}}swap(&arr[keyi], &arr[right]); return right;}

上面代碼有一處需要注意:

以下圖為例:

若存在數組中有很多個相同的值的情況,加等于號的代碼會找到很多個相同的基準值,重復調用多次函數,而不加等于號的代碼可以在一次函數調用中多次交換,避免無效的分割排序

(2)挖坑法

將left所在的位置看作坑,并設為基準值,將基準值用key保存下來,當left<right時進入循環,由于初始的坑在左側,所以right先向后移動,找比基準值小的元素,找到后將right處的下標賦給hole,值也賦給hole,此時right所在的位置成為新的坑,再到left向后移動,找比基準值大的元素,找到后將left處的下標賦給hole,值也賦給hole,此時left所在的位置成為新的坑,繼續循環。

跳出循環后,此時left和right和hole指向同一個位置,這個位置就是基準值的正確位置,將key賦給arr[hole],返回hole。

int _QuickSort1(int* arr, int left, int right)
{int hole = left;int key = arr[hole];while (left < right){while (left <right && arr[right] > arr[key]){--right;}arr[hole] = arr[right];hole = right;while (left <right && arr[left] < arr[key]){++left;}arr[hole] = arr[left];hole = left;}arr[hole] = key;return hole;
}
(3)lomuto前后指針

定義基準值為left所在的位置,把left賦給prev,cur為prev的后一個位置,當cur<=right時,進入循環,cur在前探路,找比基準值小的元素,若找到了則prev++,將prev和cur所在位置的元素對調,為了避免將同一個元素對調,可以將++prev加入到循環中,寫成如下代碼的形式。

跳出循環后,此時prev所在的位置就是基準值的正確位置,將arr[prev]和arr[keyi]對調,返回prev。

int _QuickSort2(int* arr, int left, int right)
{int keyi = left;int prev = left, cur = prev + 1;while (cur <= right){if (arr[keyi] > arr[cur] && ++prev != cur){swap(&arr[prev], &arr[cur]);}cur++;}swap(&arr[keyi], &arr[prev]);return prev;
}

2、非遞歸版本(用棧實現)

棧的作用在于保存需要排序的序列。先將數組頭尾下標入棧,當棧不為空時進入循環,取兩次棧頂元素分別賦給begin和end,取完后出棧,基準值為begin所在位置的元素,prev為begin所在位置cur為prev后一個元素的下標,prev與cur的作用與雙指針法里的作用一樣,找到基準值的正確位置后將prev賦給keyi,若keyi+1<end則將keyi和end作為新序列的頭尾下標入棧,若begin<keyi-1則將begin和keyi-1作為新序列的頭尾下標入棧,繼續循環。

void QuickSortNonR(int* arr, int left, int right)
{ST st;STInit(&st);STPush(&st, right);STPush(&st, left);while (!STEmpty(&st)){int begin = STTop(&st);STPop(&st);int end = STTop(&st);STPop(&st);int keyi = begin;int prev = begin;int cur = prev + 1;while (cur <= end){if (arr[keyi] > arr[cur] && ++prev != cur){swap(&arr[prev], &arr[cur]);}cur++;}swap(&arr[keyi], &arr[prev]);keyi = prev;if (keyi + 1 < end){STPush(&st, end);STPush(&st, keyi+1);}if (begin < keyi-1){STPush(&st, keyi-1);STPush(&st, begin);}}STDestroy(&st);
}

快速排序的時間復雜度為O(n\log n)

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

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

相關文章

uni-app iOS 上架常見問題與解決方案,實戰經驗全解析

uni-app 讓開發者能夠“一套代碼&#xff0c;多端運行”&#xff0c;極大降低了開發成本。 但當應用進入 iOS 上架階段 時&#xff0c;不少團隊發現流程并沒有想象中那么順利&#xff1a;證書問題、打包失敗、上傳出錯、審核被拒……這些都可能讓項目卡殼。 本文結合實際案例&a…

洗衣機的智能升級集成方案WT2606B屏幕驅動+AI語音控制

2025&#xff0c;洗衣機市場正從功能滿足轉向體驗升級&#xff0c;企業正面臨哪些轉型難點?一文為您解讀洗衣機行業智能化升級之路。傳統洗衣機就像是一個"沉默的工人"&#xff0c;只能通過簡單的LED指示燈告訴你它在工作&#xff0c;卻無法讓你真正了解它在干嘛。用…

機器學習進階,梯度提升機(GBM)與XGBoost

梯度提升機&#xff08;Gradient Boosting Machine, GBM&#xff09;&#xff0c;特別是其現代高效實現——XGBoost。這是繼隨機森林后自然進階的方向&#xff0c;也是當前結構化數據競賽和工業界應用中最強大、最受歡迎的算法之一。為什么推薦XGBoost&#xff1f; 與隨機森林互…

【ARMv7】開篇:掌握ARMv7架構Soc開發技能

本專欄&#xff0c;開始與大家共同總結使用ARMv7系列CPU的Soc開發技能。大概匯總了一下&#xff0c;后面再逐步完善下面的思維導圖。簡單說說&#xff1a;與通用的ARMv7-A/R相比&#xff0c;以STM32F為代表的ARMv7-M架構有以下關鍵區別和重點&#xff1a;無MMU&#xff0c;有MP…

【學術會議論文投稿】JavaScript在數據可視化領域的探索與實踐

【ACM出版 | EI快檢索 | 高錄用】2024年智能醫療與可穿戴智能設備國際學術會議&#xff08;SHWID 2024&#xff09;_艾思科藍_學術一站式服務平臺 更多學術會議請看 學術會議-學術交流征稿-學術會議在線-艾思科藍 目錄 引言 JavaScript可視化庫概覽 D3.js基礎入門 1. 引入…

CSS基礎學習步驟

好的&#xff0c;這是一份為零基礎初學者量身定制的 **CSS 學習基礎詳細步驟**。我們將從最根本的概念開始&#xff0c;通過一步一步的實踐&#xff0c;帶你穩穩地入門。 第一步&#xff1a;建立核心認知 - CSS 是做什么的&#xff1f; 1. 理解角色&#xff1a; HTML&…

MTK Linux DRM分析(三十七)- MTK phy-mtk-hdmi.c 和 phy-mtk-hdmi-mt8173.c

一、簡介 HDMI PHY驅動 HDMI 的物理層接口主要就是 HDMI Type-A 接口(19 pin),除此之外還有 Type-B、Type-C(Mini HDMI)、Type-D(Micro HDMI)、Type-E(車載專用)。 1. HDMI Type-A(常見 19-pin 標準接口) HDMI Type-A Connector Pinout ========================…

【人工智能學習之MMdeploy部署踩坑總結】

【人工智能學習之MMdeploy部署踩坑總結】報錯1&#xff1a;TRTNet: device must be a GPU!報錯2&#xff1a;Failed to create Net backend: tensorrt報錯3&#xff1a;Failed to load library libonnxruntime_providers_shared.so1. 確認庫文件是否存在2. 重新安裝 ONNX Runti…

力扣516 代碼隨想錄Day16 第一題

找二叉樹左下角的值class Solution { public:int maxd0;int result;void traversal(TreeNode* root,int depth){if(root->leftNULL&&root->rightNULL){if(depth>maxd){maxddepth;resultroot->val;}}if(root->left){depth;traversal(root->left,depth…

網格圖--Day07--網格圖DFS--LCP 63. 彈珠游戲,305. 島嶼數量 II,2061. 掃地機器人清掃過的空間個數,489. 掃地機器人,2852. 所有單元格的遠離程度之和

網格圖–Day07–網格圖DFS–LCP 63. 彈珠游戲&#xff0c;305. 島嶼數量 II&#xff0c;2061. 掃地機器人清掃過的空間個數&#xff0c;489. 掃地機器人&#xff0c;2852. 所有單元格的遠離程度之和 今天要訓練的題目類型是&#xff1a;【網格圖DFS】&#xff0c;題單來自靈茶山…

多功能修改電腦機器碼序列號工具 綠色版

多功能修改電腦機器碼序列號工具 綠色版電腦機器碼序列號修改軟件是一款非常使用的數據化虛擬修改工具。機器碼修改軟件可以虛擬的定制您電腦上的硬件信息&#xff0c;軟件不會對您的電腦造成傷害。軟件不需要您有專業的知識&#xff0c;就可以模擬一份硬件信息。機器碼修改軟…

React Hooks深度解析:useState、useEffect及自定義Hook最佳實踐

React Hooks自16.8版本引入以來&#xff0c;徹底改變了我們編寫React組件的方式。它們讓函數組件擁有了狀態管理和生命周期方法的能力&#xff0c;使代碼更加簡潔、可復用且易于測試。本文將深入探討三個最重要的Hooks&#xff1a;useState、useEffect&#xff0c;以及如何創建…

期權平倉后權利金去哪了?

本文主要介紹期權平倉后權利金去哪了&#xff1f;期權平倉后權利金的去向需結合交易角色&#xff08;買方/賣方&#xff09;、平倉方式及市場價格變動綜合分析&#xff0c;具體可拆解為以下邏輯鏈條。期權平倉后權利金去哪了&#xff1f;1. 買方平倉&#xff1a;權利金的“差價…

2025國賽C題題目及最新思路公布!

C 題 NIPT 的時點選擇與胎兒的異常判 問題 1 試分析胎兒 Y 染色體濃度與孕婦的孕周數和 BMI 等指標的相關特性&#xff0c;給出相應的關系模 型&#xff0c;并檢驗其顯著性。 思路1&#xff1a;針對附件中孕婦的 NIPT 數據&#xff0c;首先對數據進行預處理&#xff0c;并對多…

NLP技術爬取

“NLP技術爬取”這個詞組并不指代一種單獨的爬蟲技術&#xff0c;而是指將自然語言處理&#xff08;NLP&#xff09;技術應用于網絡爬蟲的各個環節&#xff0c;以解決傳統爬蟲難以處理的問題&#xff0c;并從中挖掘出更深層次的價值。簡單來說&#xff0c;它不是指“用NLP去爬”…

讓錄音變得清晰的軟件:語音降噪AI模型與工具推薦

在數字內容創作日益普及的今天&#xff0c;無論是播客、線上課程、視頻口播&#xff0c;還是遠程會議&#xff0c;清晰的錄音質量都是提升內容專業度和觀眾體驗的關鍵因素之一。然而&#xff0c;由于環境噪音、設備限制等因素&#xff0c;錄音中常常夾雜各種干擾聲音。本文將介…

大話 IOT 技術(1) -- 架構篇

文章目錄前言拋出問題現有條件初步設想HTTP 與 MQTT中間的服務端完整的鏈路測試的虛擬設備實現后話當你迷茫的時候&#xff0c;請點擊 物聯網目錄大綱 快速查看前面的技術文章&#xff0c;相信你總能找到前行的方向 前言 Internet of Things (IoT) 就是物聯網&#xff0c;萬物…

【wpf】WPF 自定義控件綁定數據對象的最佳實踐

WPF 自定義控件綁定數據對象的最佳實踐&#xff1a;以 ImageView 為例 在 WPF 中開發自定義控件時&#xff0c;如何優雅地綁定數據對象&#xff0c;是一個經常遇到的問題。最近在實現一個自定義的 ImageView 控件時&#xff0c;我遇到了一個典型場景&#xff1a; 控件內部需要使…

[Dify 專欄] 如何通過 Prompt 在 Dify 中模擬 Persona:即便沒有專屬配置,也能讓 AI 扮演角色

在 AI 應用開發中,“Persona(角色扮演)”常被視為塑造 AI 個性與專業邊界的重要手段。然而,許多開發者在使用 Dify 時會疑惑:為什么我在 Chat 應用 / Agent 應用 / Workflow 里都找不到所謂的 Persona 配置項? 答案是:Dify 平臺目前并沒有內建的 Persona 配置入口。角色…

解決雙向循環鏈表中對存儲數據進行奇偶重排輸出問題

1. 概念 對鏈表而言,雙向均可遍歷是最方便的,另外首尾相連循環遍歷也可大大增加鏈表操作的便捷性。因此,雙向循環鏈表,是在實際運用中是最常見的鏈表形態。 2. 基本操作 與普通的鏈表完全一致,雙向循環鏈表雖然指針較多,但邏輯是完全一樣。基本的操作包括: 節點設計 初…