經典排序算法詳解

目錄

創作不易,如對您有幫助,還望一鍵三連,謝謝!

前言

學習目標:

直接插入排序

基本思想:

代碼

希爾排序:

gap取值

代碼

特性總結

選擇排序

基本思想

代碼

堆排序

思想

代碼

冒泡排序:

快速排序:

思想

遞歸

非遞歸

歸并排序

基本思想:

遞歸實現

非遞歸實現

時間復雜度與空間復雜度以及穩定性


創作不易,如對您有幫助,還望一鍵三連,謝謝!

前言

排序在我們日常生活中十分常見,比如:成績按高低排序,購物網頁按價格排序......今天我們就來學習常見的幾個排序算法。

學習目標:

接下來我們一個一個講解。

直接插入排序

首先,我們先來看動圖:

基本思想:

end從0開始,[0,end]視為一個有序的數組,然后每次都讓end+1的數據與前面有序數組[0,end]進行對比排序,然后end++,直至遍歷完整個數組,此時原數組就有序了。

代碼

有小伙伴可能會問,為什么最后要pa[end+1]=tem ?且看此圖:

這就是上面問題的原因,其實學習數據結構時,有這種問題究其原因還是因為沒有畫圖,筆者認為學習數據結構一定要多畫圖,這樣才不容易出錯,有點跑題了哈哈,我們繼續學習下一個排序。

希爾排序:

首先,希爾排序其實就是直接插入排序的變形,所以要理解希爾排序,我們得熟練掌握直接插入排序。我們先來看一下動圖:

是不是看的一臉懵?這就對了,這個思路還是有點抽象的,容筆者慢慢講解:

首先,我們要知道希爾排序其實就是直接插入排序的優化,它選取了一個值gap,并把數組分成gap個組,每個組兩個元素相隔gap個位置,如下圖所示:

至于gap如何取值,我們一會兒再講,如上圖,我們講數組分成了gap組(5組),每組兩兩元素之間相隔gap個位置。

然后,我們對每一組進行直接插入排序,結果如下:

然后gap=gap/2,此時gap為2,在把數組分成gap(2)組,每組相鄰元素相差gap位置,如下:

在對每組進行直接插入排序,排好后如下:

然后gap為1,將數組分成了1組,有10個元素,對改組進行直接插入排序:

自此,數組有序。

有小伙伴可能發現了,當gap為1時不就是直接插入排序嗎?沒錯所以會說希爾排序就是插入排序的變形,實際上希爾排序就是插入排序的優化,希爾排序可比插入排序快多了。關于各排序的時間復雜度,我們下篇文章在講解。

gap取值

gap取值的話

一般取法有多種,其中兩種常見的是:

  1. 取 n/2

    • 最初的增量(gap)設定為數組長度的一半,即?gap = n / 2
    • 然后每次將 gap 減半,直到 gap = 1。
  2. 取 n/3+1

    • 初始增量(gap)設定為?gap = n / 3 + 1
    • 然后每次將 gap 按一定規則縮小,直到 gap = 1。

上面我們就是用了第一種方法。

當gap>1時,被稱作為預排序;當ga1p=1為插入排序。

代碼

代碼如下:

果然,當我們了解思路后寫代碼,發現還是一樣難寫,哈哈哈。

第一個for循環,是控制所有組,確保每一組都能進行排序,一共有gap組,故為i<gap.

而這段代碼,就是控制一組的排序,這個過程其實就是插入排序的變形,當gap=1時,與插入排序一模一樣,我們可以畫圖來進行理解。

需要注意的是j<n-gap:

因為我們進行排序時,有pa[end+gap]=pa[end],所以我們要讓j<n-gap,防止越界。

希爾排序還有另外一種寫法:

這個寫法與第一個不同的是沒有按照先排好一個組,然后再排另一個組,它直接是混著排序,小伙伴們可以畫圖理解一下。兩種方法掌握一種即可。

特性總結

選擇排序

基本思想

每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的 數據元素排完 。

這個排序思路還是比較簡單的,

代碼

好,我們給個樣例運行一下:

不出意外,錯了!

為啥呢?我們來調試一下:

第一輪,maxi為0,mini為9,沒有錯,我們在進行下面的交換代碼。

出問題了,當我們把pa[begin]和pa[mini]進行交換時,由于maxi的值與begin相等,所以當交換pa[begin]和pa[mini]后,maxi指向的值就變了,不是最大值了,所以我們要加一個if條件語句:

這下就對了。

堆排序

思想

首先建堆,升序建大堆,降序建小堆,建好堆之后另end等于數組長度-1,交換0位置和end位置的數據,向下調整建堆end--,直至end小于0。

代碼

這個堆排序寫起來還是有難度的,這里看不懂也沒關系,筆者之后專門寫一篇堆排序的文章,可以暫時跳過繼續往下看。

冒泡排序:

這個就比較簡單了,冒泡排序沒有什么實踐價值,但有一定的教學意義,我們來看一下動圖:

代碼如下:

快速排序:

思想

我們找一個參考值,end指向數組尾部,begin指向數組起始位置。

end先走,如果arr[end]大于key,end--直至找到小于key的位置;

同理,當end找到小于key的位置后,begin開始找大于key的位置,然后交換begin和end兩位置的值,直至begin=end。

當begin和end相遇時的位置的值一定小于key。(原因我們一會兒講),然后交換key和兩者相遇位置的值,完成第一趟排序。

快排是比較重要的,還是有很大的概率在面試時讓你手撕,所以我們一定要熟練掌握,快排實現有遞歸和非遞歸兩種方法,我們一一講解。

遞歸

排完一次序后,以keyi為基準分割區間,繼續排序.

代碼如下:

非遞歸

有小伙伴可能會說:我們都已經會遞歸版本的快排了,還有必要學這個嗎?往年一個面試官是這樣問的:同學,你學過數據結構,那你了解快排嗎?這位同學非常熟練的講出來了遞歸實現的大致思路。面試官聽后笑著說:“很好,那你能用非遞歸實現嗎?”哈哈哈,所以還是有必要的。

非遞歸和遞歸思路一樣,我們也是采用分割區間,不能用遞歸,我們可以用循環來解決,那么問題來了,我們怎么來存儲分割好的區間呢?

想想我們之前講過一道括號匹配的問題,那個時候我們怎么存儲括號的?

答案是:棧。

我們用棧來存儲分割后的區間,只要區間滿足左邊界大于右邊界就入棧,然后套一個while循環,當戰不為空就繼續。

需要注意的是棧是后進先出,千萬不要把區間搞反了

代碼如下:

歸并排序

基本思想:

歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合并,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合并成一個有序表,稱為二路歸并。

說的通俗易懂點就是把一個數組分解成兩個數組pa1,pa2,直到每個數組只有一個元素,然后在依次合并pa1和pa2,從而使原數組有序。

歸并排序的思想很像我們之前講過的合并兩個有序數組,不知道小伙伴還記不記得,只能說是一模一樣,同樣,實現歸并排序也有遞歸和非遞歸兩種方式。

遞歸實現

需要講的一點是_MergeSort是MergeSort的子函數,也可以稍作修改,寫在一起.還有就是記得釋放動態開辟的內存,養成良好的代碼風格。

下面是遞歸大致展開圖,可以幫助大家理解一下:

非遞歸實現

非遞歸實現,怎么實現呢?我們上面快排的非遞歸實現運用了棧來解決,那么這里能用棧來解決問題嗎?可以,但是這里就比較麻煩,如果我們用棧來解決的話,那么循環的結束條件難以判斷,同時此處棧管理起來也比較麻煩。我們這里可以用迭代來實現。

需要注意的是,我們每次要歸并的兩組數據,end1,begin2,end2有可能會越界,因為for循環的判斷條件是i<n-1,此時除了begin1其余三個都可能會越界,所以我們要判斷修正。

當begin2越界時,代表第二組越界,也就是不存在,所以不需要歸并;當只有end2越界時,只需把end2修正為最后一個元素繼續歸并即可。其余也就沒什么好說的了。

時間復雜度與空間復雜度以及穩定性

首先,我們先來了解一下穩定性的概念:

穩定性:假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次 序保持不變,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,則稱這種排 序算法是穩定的;否則稱為不穩定的。

如上圖所示,即排完序后,黑6與紅6的相對位置不變(黑6還在紅6前面),那么這個排序就是穩定的。

知道了這個,我們接下來一個一個分析上面各個排序算法的時間復雜度、空間復雜度以及穩定性

1.直接插入排序

穩定性:穩定

時間復雜度:O(N^2);

空間復雜度:O(1)。

直接插入排序[0,end]有序,讓arr[end+1]與[0,end]進行比較交換,當兩數相等時,我們可以讓其不交換,那么最后拍完序相等元素的相對順序是不變的,所以說直接插入排序是穩定的。

通過上面的代碼,不難分析出直接插入排序的時間復雜度為O(n^2),由于沒開辟新的空間,所以說空間復雜度為O(1)。

2.希爾排序

穩定性:不穩定

時間復雜度:O(N*logN)

空間復雜度:O(1)

我們上面講,希爾排序是插入排序的變形,那么希爾排序穩定嗎?答案是不穩定

故希爾排序不穩定。那么希爾排序的時間復雜度又為多少呢?

這個就很復雜了,因為希爾排序循環次數與gap的取值有關,而gap又有很多種不同的取值方法,

同時,while循環比較次數和元素移動的次數也難以計算,所以說這需要很強的數學專業知識,筆者不會,但有大佬給出希爾排序的時間復雜度大概為O(N^1.3),記住就行。

那么希爾排序的空間復雜度為多少呢?很顯然是O(1)。

3.選擇排序

穩定性:不穩定。

時間復雜度:O(N^2);

空間復雜度:O(1)。

選擇排序為什么不穩定的,這是個易錯點,我們看下圖的分析:

這種情況就是不穩定的情況。時間復雜度空間復雜度比較簡單,不再贅述.

4.堆排序

穩定性:不穩定。

時間復雜度:O(n*logN)

空間復雜度:O(1)

由于堆我們之前沒有講解,講起來有一點麻煩,我們先放一下,之后專門講解堆的相關知識。

5.冒泡排序

穩定性:穩定

時間復雜度:O(N^2);

空間復雜度:O(1);

6.快速排序

穩定性:不穩定。

時間復雜度:O(N*logN);

空間復雜度:O(? logn)~O(n)。

快排也無法保證相等元素的相對位置,這個很好想例子,比如下圖?:

這里的易錯點就是空間復雜度不是O(1)!!!

函數遞歸需要額外開辟空間,我們上面也講了,快排通常是遞歸實現的,N個數組成的數組每次被分成兩個區間,依次分割,直到left>=right,它一共分了logN次,故需要開辟logN個新的空間

有小伙伴會問,遞歸遞歸,它往回歸的時候,不是又應該開辟一塊新空間嗎?好問題,函數遞歸,回歸時用的是已經開辟好了的空間。這涉及到函數棧幀的問題,有興趣的小伙伴可以去學習學習,增強內力。

7.歸并排序

穩定性:穩定

時間復雜度:O(N*logN).

空間復雜度:O(N).

也沒什么好說的,比較簡單。

總結圖:

筆者希望大家能夠理解性的去記憶這些東西,理解它們的原理,這樣記憶起來就事半功倍了。

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

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

相關文章

[CTF]-PWN:mips反匯編工具,ida插件retdec的安裝

IDA是沒有辦法直接按F5來反匯編mips的匯編的&#xff0c;而較為復雜的函數直接看匯編不太現實&#xff0c;所以只能借用插件來反匯編 先配置環境&#xff0c;下載python3.4以上的版本&#xff0c;并將其加入到環境變量中 下載retdec 地址&#xff1a;Release v1.0-ida80 ava…

蘋果開發者證書申請流程

蘋果開發者證書申請流程&#xff1a; 1.Certificates 后面加號 2.iOS Distribution (App Store and Ad Hoc) 點擊continue 3.選擇Upload a Certificate Signing Request To manually generate a Certificate, you need a Certificate Signing Request (CSR…

Unity關于Addressables.Release釋放資源內存問題

前言 最近在編寫基于Addressables的資源管理器&#xff0c;對于資源釋放模塊配合MemoryProfiler進行了測試&#xff0c;下面總結下測試Addressables.Release的結論。 總結 使用Addressables.Release釋放資源時&#xff0c;通過MemoryProfiler檢查內存信息發現加載的內容還在…

多租戶與低代碼開發的應用:解鎖企業數字化轉型的無限可能

在數字化轉型的浪潮中&#xff0c;多租戶與低代碼開發已經成為推動企業快速、靈活、安全地構建和部署應用的關鍵技術。本文將深入探討這兩種技術的結合如何為企業帶來前所未有的變革和機遇。 多租戶架構&#xff1a;資源共享與隔離的藝術 多租戶架構&#xff0c;是一種高級的軟…

一文讓你簡單明了的知道云管理平臺的作用

隨著云計算的飛速發展&#xff0c;越來越多的企業實現了上云。因此云管理平臺也在云計算環境中扮演著至關重要的角色&#xff0c;在企業上云后充分發揮作用。今天我們小編就來為大家簡單講解一下云管平臺的作用。 一文讓你簡單明了的知道云管理平臺的作用 作用1、提高工作效率…

思考-生涯思考-GPT-5對人們的影響

GPT-5 一年半后發布&#xff1f;對此你有何期待&#xff1f; IT之家6月22日消息&#xff0c;在美國達特茅斯工程學院周四公布的采訪中&#xff0c;OpenAI首席技術官米拉穆拉蒂被問及GPT-5是否會在明年發布&#xff0c;給出了肯定答案并表示將在一年半后發布。此外&#xff0c;…

20240629 每日AI必讀資訊

&#x1f680; Google 深夜突襲&#xff0c;Gemma 2 狂卷 Llama 3 - Gemma2性能超越Llama3&#xff0c;提供9B和27B版本&#xff0c;性能接近70B模型但大小僅為其40% - Gemma2支持高效推理&#xff0c;單個GPU即可實現全精度推理&#xff0c;廣泛的硬件支持 - Gemma2兼容多種…

CMake之嵌套的CMakeLists

文章目錄 前言項目結構節點關系如何嵌套多個cmake示例程序cmake 總結 前言 在現代軟件開發中&#xff0c;CMake 是一個非常重要的工具&#xff0c;它允許開發者編寫可移植的構建腳本來管理項目。對于大型項目&#xff0c;通常會有多個模塊或子項目&#xff0c;這時候就需要用到…

2024年618各城市跨境電商戰況如何?

2024年618各城市 跨境電商戰況如何? 2024 城市“618”跨境戰績&#xff08;部分&#xff09; 2024年“618”期間&#xff0c;全國跨境電商交易額實現2,397.12億元&#xff0c;同比增長8.68%。從跨境商品來看&#xff0c;進口端&#xff0c;嬰童食品、美容美妝、營養保健等商…

numpy.random.seed()使用

import numpy as npnp.random.seed(2) # 生成隨機種子2 一次使用機會 作用在下一個隨機數生成的時候 a np.random.random() # 使用隨機種子2 b np.random.random() # 因為隨機種子使用完了 &#xff01; 這里使用默認按系統根據時間作為seed參數的隨機種子 print(a) # 隨…

手機取證基礎知識(一)

文章關鍵詞&#xff1a;手機取證、電子數據取證 手機取證&#xff0c;也稱為移動設備取證或智能手機取證&#xff0c;是數字取證的一個分支&#xff0c;專注于從智能手機和其他移動設備中提取、分析和呈現證據的過程。這項技術通常用于法律調查&#xff0c;尤其是在犯罪調查中…

關于 AI 音樂大模型的研究報告

摘要&#xff1a;本研究報告聚焦于近期上線的音樂大模型&#xff0c;探討其對音樂創作門檻的降低影響&#xff0c;分析其引發的關于音樂圈是否會被 AI 徹底顛覆的討論&#xff0c;以及深入研究與之相關的版權歸屬和創意產業在 AI 影響下的發展等問題。 一、引言 在過去的一個月…

JavaScript(1)——JS介紹

JS是什么 是一種運行在客戶端&#xff08;瀏覽器&#xff09;的編程語言&#xff0c;實現人機交互的效果 作用&#xff08;做什么&#xff09; 網頁特效&#xff08;監聽用戶的一些行為讓網頁做出對應的反饋&#xff09;表單驗證&#xff08;針對表單數據的合法性行為進行判…

PHP實戰:輕松實現商品庫存批量導入,高效管理不是夢!

在電商平臺上&#xff0c;批量導入商品庫存是一個常見的需求。通過批量導入&#xff0c;商家可以快速更新大量商品的庫存信息&#xff0c;提高工作效率。本文將介紹如何使用PHP編程語言實現這一功能&#xff0c;方便商家進行庫存管理。 首先&#xff0c;我們需要創建一個表格文…

[深度學習] 前饋神經網絡

前饋神經網絡&#xff08;Feedforward Neural Network, FFNN&#xff09;是人工神經網絡中最基本的類型&#xff0c;也是許多復雜神經網絡的基礎。它包括一個輸入層、一個或多個隱藏層和一個輸出層。以下是詳細介紹&#xff1a; 1. 結構 1. 輸入層&#xff08;Input Layer&am…

【Android 構建新工具】Bazel 構建Android項目

【Android 構建新工具】Bazel 構建Android項目 本文我們使用Bazel構建一個最簡單的Android項目。Bazel提供了編譯Android程序內置的方法,具體參考:Android Rules 1. 環境準備 Bazel只是編譯工具,不是真正的編譯器,所以還是需要Andorid開發的SD、NDK以及Android Studio,…

基于改進天鷹優化算法(IAO)優化支持向量機(SVM)數據分類預測(IAO-SVM)

改進天鷹優化算法(IAO)見&#xff1a;【智能優化算法】改進的AO算法(IAO)-CSDN博客 支持向量機(SVM)數據分類預測&#xff1a;基于支持向量機(SVM)的數據分類預測-CSDN博客 代碼原理 基于改進天鷹優化算法&#xff08;IAO&#xff09;優化支持向量機&#xff08;SVM&#xf…

uniapp獲取證書秘鑰、Android App備案獲取公鑰、簽名MD5值

一、 uniapp獲取證書秘鑰 打開uniapp開發者中心下載證書打開cmd輸入以下這段代碼&#xff0c;下載提供查看到的密鑰證書密碼就可以了&#xff01;下載證書在 java 環境下運行才可以 // your_alias 換成 證書詳情中的別名&#xff0c;your_keystore.keystore 改成自己的證書文件…

Splashtop 的屏幕錄制功能如何提高 IT 合規性

在當今的數字時代&#xff0c;隨著遠程辦公的普及以及監管要求和網絡安全威脅的加劇&#xff0c;IT 副總裁、首席信息官&#xff08;CIO&#xff09;等 IT 管理人員面臨著一系列獨特挑戰。 各組織在遠程支持運營中要全力維護合規性、提高安全性并堅持問責制&#xff0c;技術解…

漢江師范學院2024年成人高等繼續教育招生簡章

漢江師范學院&#xff0c;這所承載著深厚文化底蘊和學術積淀的高等學府&#xff0c;即將在2024年迎來新一季的成人高等繼續教育招生。這不僅是一次知識的盛宴&#xff0c;更是對每一位懷揣夢想、追求進步的成年人的誠摯邀請。 漢江師范學院&#xff0c;以其嚴謹的教學態度、卓…