七種常見經典排序演算法總結 C

2022-07-23 06:54:17 字數 4331 閱讀 2636

最近想複習下c++,很久沒怎麼用了,畢業時的一些經典排序演算法也忘差不多了,所以剛好一起再學習一遍。

除了冒泡、插入、選擇這幾個複雜度o(n^2)的基本排序演算法,希爾、歸併、快速、堆排序,多多少少還有些晦澀難懂,幸好又大神dreamcatcher-cx都總結成了**,一步步很詳細,十分感謝。

而且就時間複雜度來說,這幾種演算法到底有什麼區別呢,剛好做了下測試。

**參考: 

//

: basic_sort

#include

#include

#include

#include

using

namespace

std;

//獲取函式名字的巨集

#define get_name(x) #x

//生成隨機數的巨集

#define random(a,b) (rand()%(b-a+1)+a)

//列印容器物件(vector)的巨集

#define prt(nums) \}/*

氣泡排序

基本思想: 對相鄰的元素進行兩兩比較,順序相反則進行交換,這樣,每一趟會將最小或最大的元素「浮」到頂端,最終達到完全有序

**:

考的最多的排序了吧。

1. 兩層迴圈,最裡面判斷兩個數的大小,大的換到後面(正序)

2. 內部迴圈一遍後,最大的數已經到最後面了

3. 下一次內部迴圈從0到倒數第二個數(最後乙個數通過第一步迴圈比較已經最大了)

4. 依次迴圈下去

時間複雜度o(n^2),空間複雜度是o(n) */

void bubble_sort(vector &nums)

}}}/*

插入排序

基本思想: 每一步將乙個待排序的記錄,插入到前面已經排好序的有序序列中去,直到插完所有元素為止。

**:

1. 兩層迴圈,第一層i表示從左開始已經排好虛的部分

2. 第二層迴圈,將當前的數以及它前面的所有數兩兩比較,交換大的數到後面(正序)

3. 保證前面的數是排序好的,將新讀取的數通過遍歷前面排好序的部分並比較,插入到合適的位置

時間複雜度o(n^2),空間複雜度是o(n) */

void insert_sort(vector &nums)

}}}/*

選擇排序

**:

基本思想: 每一趟從待排序的資料元素中選擇最小(或最大)的乙個元素作為首元素

1. 兩層迴圈,第一層從左到右遍歷,讀取當前的數

2. min存放最小元素,初始化為當前數字

3. 內部迴圈遍歷和比較當前數字後後面所有數字的大小,如果有更小的,替換min為更小數字的位置

4. 內部遍歷之後檢查min是否變化,如果變化,說明最小的數字不在之前初始化的min位置,交換使每次迴圈最小的元素被移動到最左邊。

時間複雜度o(n^2),空間複雜度是o(n) */

void selection_sort(vector &nums)

}if (min != i)

}}/*

希爾排序

**:

1. 最外層迴圈設定間隔(gap),按常規取gap=length/2,並以gap = gap/2的方式縮小增量

2. 第二個迴圈從gap位置向後遍歷,讀取當前元素

3. 第三個迴圈從當前元素所在分組的上乙個元素開始(即減去gap的位置),通過遞減gap向前遍歷分組內的元素,其實就是比較分組內i和i-gap元素的大小,交換大的到後面

希爾排序的時間複雜度受步長的影響,不穩定。 */

void shell_sort(vector &nums)

}}}//

合併兩個有序序列

void merge_array(vector &nums, int b, int m, int e, vector &temp)

//遞迴對序列拆分,從b(開始)到e(結束)的序列,取中間點(b + e) / 2拆分

void merge_sort_recur(vector &nums, int b, int e, vector &temp)}/*

歸併排序

**:

基本思想: 利用歸併的思想實現的排序方法,該演算法採用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然後遞迴求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。

1. 合併兩個有序序列的函式,合併後結果存入臨時的temp

2. 從中間分,一直遞迴分到最小序列,即每個序列只有乙個元素,單位為1(乙個元素肯定是有序的)

3. 然後兩兩比較合併成單位為2的n/2個子陣列,在結果上繼續兩兩合併

時間複雜度是o(nlogn),空間複雜度是o(n)。 */

void merge_sort(vector &nums)

//將啟始位置b作為基準,大於基準的數移動到右邊,小於基準的數移動到左邊

void quick_sort_recur(vector &nums, int b, int

e) swap(nums[b], nums[lb]);

//cout << "nums: ";

//prt(nums);

//cout << endl;

quick_sort_recur(nums, b, lb);

quick_sort_recur(nums, lb + 1

, e);

}}/*

快速排序

**:

基本思想: 快速排序也是利用分治法實現的乙個排序演算法。快速排序和歸併排序不同,它不是一半一半的分子陣列,而是選擇乙個基準數,把比這個數小的挪到左邊,把比這個數大的移到右邊。然後不斷對左右兩部分也執行相同步驟,直到整個陣列有序。

1. 用乙個基準數將陣列分成兩個子陣列,取第乙個數為基準

2. 將大於基準數的移到右邊,小於的移到左邊

3. 遞迴的對子陣列重複執行1,2,直到整個陣列有序

空間複雜度是o(n),時間複雜度不穩定。 */

void quick_sort(vector &nums)

//調整單個二叉樹的根節點和左右子樹的位置,構建大頂堆

//在左右子樹中挑出最大的和根節點比較,把最大的數放在根節點即可

void max_heapify(vector &nums, int root, int

end)

if (nums[curr] else

}}/*

堆排序 **:

基本思想: 將待排序序列構造成乙個大頂堆,此時,整個序列的最大值就是堆頂的根節點。將其與末尾元素進行交換,此時末尾就為最大值。然後將剩餘n-1個元素重新構造成乙個堆,這樣會得到n個元素的次小值。如此反覆執行,便能得到乙個有序序列了

堆的概念(i是乙個二叉樹的根節點位置,2i+1和2i+2分別是左右子樹):

大頂堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]

小頂堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]

1. 由底(最後乙個有葉子的根節點n/2-1)自上構建大頂堆

2. 根節點(0)和末尾交換,末尾變為最大

3. 對餘下的0到n-1個數的根節點(0)二叉樹進行大頂堆調整(呼叫max_heapify)(根節點(0)的葉子節點已經大於下面的所有數字了)

堆執行一次調整需要o(logn)的時間,在排序過程中需要遍歷所有元素執行堆調整,所以最終時間複雜度是o(nlogn)。空間複雜度是o(n)。 */

void heap_sort(vector &nums)

for (int i = n - 1; i > 0; i--)

}void func_excute(void(* func)(vector &), vector nums, string

func_name)

intmain()

///:~

在陣列很小的情況下,沒有太大區別。但是較長陣列,考的最多的氣泡排序就明顯比較吃力了~

具體原因只能從時間複雜度上面來看,但為什麼差這麼多,我也不是完全明白~

執行結果,排序演算法分別耗時:

陣列長度: 5000; 

bubble_sort耗時:183.4 (ms)

insert_sort耗時:106.525 (ms)

selection_sort耗時:68.036 (ms)

shell_sort耗時:1.096 (ms)

merge_sort耗時:1.226 (ms)

quick_sort耗時:1.398 (ms)

heap_sort耗時:1.514 (ms)

program ended with exit code: 0

C 實現七種經典排序演算法

具體的排序方法如下所示 1 氣泡排序 基本思想 比較相鄰的兩個數,如果前者比後者大,則進行交換。每一輪排序結束,選出乙個未排序中最大的數放到陣列後面。常見氣泡排序演算法如下所示 void bubblesort int arr,int n 公升級版氣泡排序法 通過從低到高選出最大的數放到後面,再從高到...

七種排序演算法總結

根據排序過程中借助的主要操作,將7種內排序演算法按照下圖所示進行分類。將7種演算法的各種指標進行對比,如下表所示。從平均情況來看,顯然最後3種改進演算法要勝過希爾排序,並遠遠勝過前3種簡單演算法。從最好情況看,反而冒泡和直接插入排序要更勝一籌,也就是說,如果待排序列總是基本有序,反而不應該考慮四種複...

七種常用排序演算法總結

1.氣泡排序 bubble sort package com.zha.wmls.sort 氣泡排序 每一輪找出乙個最大的,放在最後面,穩定 時間複雜度為n 2 public class bubblesort long befortime system.currenttimemillis sort a...