排序演算法總結2一非比較排序

2021-08-31 03:12:06 字數 3291 閱讀 6948

目錄

一. 計數排序(countingsort)

二. 基數排序(radixsort)

二.桶排序(bucketsort)

這篇文章中我們來**一下常用的非比較排序演算法:計數排序基數排序桶排序。在一定條件下,它們的時間複雜度可以達到o(n)。

這裡我們用到的唯一資料結構就是陣列,當然我們也可以利用鍊錶來實現下述演算法。

基本思想:

計數排序用到乙個額外的計數陣列c,根據陣列c來將原陣列a中的元素排到正確的位置。

通俗地理解,例如有10個年齡不同的人,假如統計出有8個人的年齡不比小明大(即小於等於小明的年齡,這裡也包括了小明),那麼小明的年齡就排在第8位,通過這種思想可以確定每個人的位置,也就排好了序。當然,年齡一樣時需要特殊處理(保證穩定性):通過反向填充目標陣列,填充完畢後將對應的數字統計遞減,可以確保計數排序的穩定性。

過程:

平均時間複雜度:o(n + k)

計數排序的時間複雜度和空間複雜度與陣列a的資料範圍(a中元素的最大值與最小值的差加上1)有關,因此對於資料範圍很大的陣列,計數排序需要大量時間和記憶體。

c++**實現:

// 分類 ------------ 內部非比較排序

// 資料結構 --------- 陣列

// 最差時間複雜度 ---- o(n + k)

// 最優時間複雜度 ---- o(n + k)

// 平均時間複雜度 ---- o(n + k)

// 所需輔助空間 ------ o(n + k)

// 穩定性 ----------- 穩定

const int n = 100; // 基數為100,排序[0,99]內的整數

int c[n]; // 計數陣列

void countingsort(int arr,int len,int c)

for(int m=0;m

基本思想:

將所有待比較正整數統一為同樣的數字長度,數字較短的數前面補零。然後,從最低位開始進行基數為10的計數排序,一直到最高位計數排序完後,數列就變成乙個有序序列(利用了計數排序的穩定性)。

過程:

下圖給出了對進行基數排序的簡單演示過程

平均時間複雜度:o(n * dn)

基數排序的時間複雜度是o(n * dn),其中n是待排序元素個數,dn是數字位數。這個時間複雜度不一定優於o(n log n),dn的大小取決於數字位的選擇(比如位元位數),和待排序資料所屬資料型別的全集的大小;dn決定了進行多少輪處理,而n是每輪處理的運算元目。

如果考慮和比較排序進行對照,基數排序的形式複雜度雖然不一定更小,但由於不進行比較,因此其基本操作的代價較小,而且如果適當的選擇基數,dn一般不大於log n,所以基數排序一般要快過基於比較的排序,比如快速排序。由於整數也可以表達字串(比如名字或日期)和特定格式的浮點數,所以基數排序並不是只能用於整數排序。

c++**實現:

// 分類 ------------- 內部非比較排序

// 資料結構 ---------- 陣列

// 最差時間複雜度 ---- o(n * dn)

// 最優時間複雜度 ---- o(n * dn)

// 平均時間複雜度 ---- o(n * dn)

// 所需輔助空間 ------ o(n * dn)

// 穩定性 ----------- 穩定

const int dn = 3; // 待排序的元素為三位數及以下

const int n = 10; // 基數為10,每一位的數字都是[0,9]內的整數

int c[k]; // 計數陣列

int getdigit(int x, int d) // 獲得元素x的第d位數字

;// 最大為三位數,所以這裡只要到百位就滿足了

return (x / radix[d]) % 10;

}void countingsort(int arr,int len,int c,int d)

for(int m=0;m

基本思想:

桶排序也叫箱排序。工作的原理是將陣列元素對映到有限數量個桶裡,利用計數排序可以定位桶的邊界,每個桶再各自進行桶內排序(使用其它排序演算法或以遞迴方式繼續使用桶排序)。

過程:

下圖給出了對進行桶排序的簡單演示過程

平均時間複雜度:o(n),保證各個桶內元素個數均勻即可

桶排序不是比較排序,不受到o(nlogn)下限的影響,它是鴿巢排序的一種歸納結果,當所要排序的陣列值分散均勻的時候,桶排序擁有線性的時間複雜度。

c++**實現:

// 分類 ------------- 內部非比較排序

// 資料結構 --------- 陣列

// 最差時間複雜度 ---- o(nlogn)或o(n^2),只有乙個桶,取決於桶內排序方式

// 最優時間複雜度 ---- o(n),每個元素佔乙個桶

// 平均時間複雜度 ---- o(n),保證各個桶內元素個數均勻即可

// 所需輔助空間 ------ o(n + bn)

// 穩定性 ----------- 穩定

/* 本程式用陣列模擬桶 */

const int bn = 5; // 這裡排序[0,49]的元素,使用5個桶就夠了,也可以根據輸入動態確定桶的數量

int c[bn]; // 計數陣列,存放桶的邊界資訊

void insertsort(int arr,int l,int r)

}int maptobucket(int x)

void countingsort(int arr, int len)

for (int m=0;m

常用排序演算法總結(2) 非比較排序演算法

主要有氣泡排序,選擇排序,插入排序,歸併排序,堆排序,快速排序等。在一定條件下,它們的時間複雜度可以達到o n 需要三個陣列 待排序陣列 int arr new int 輔助計數陣列 int help new int max min 1 該陣列大小為待排序陣列中的最大值減最小值 1 輸出陣列 int...

非比較排序

以下內容參考自 演算法導論 基於比較的排序演算法可以用一顆完全二叉樹 決策樹 來表示,節點表示每一次的比較過程,葉子節點表示最終的排序順序,葉子節點一共有n 個 n表示資料個數,一共有n 種排列方式 二叉樹的高度h就是比較的次數,由二叉樹的性質,葉子節點的個數不大於2 h,所以有 2 h n 2 h...

非比較排序

計數排序 n個輸入元素的每乙個都是在0到k之間的整數 k為某個整數 1.假設輸入陣列是a 1.n 還需要兩個陣列 b 1.n 存放排序的輸出,c 0.k 提供臨時儲存空間 2.c i 中存放等於 i 的元素的個數,i 0,1,k 3.通過相加計算確定有多少元素是小於等於i的 4.把每個元素a i 放...