演算法導論學習之線性時間排序 排序演算法穩定性總結

2021-06-29 02:54:06 字數 2264 閱讀 3308

前面我們學習的幾種排序演算法都是基於比較的,對於任何輸入資料他們都是適用的,其最壞的時間複雜度不會低於nlgn;

但對於一些比較特殊的輸入資料,我們可以不採取比較的方法而是採用其它的方法對其進行排序,以達到線性的時間複雜度。下面就來介紹三種這樣的演算法:計數排序,基數排序,桶排序(因為這幾種演算法不常見,我只實現了計數排序,其它兩種排序演算法用偽**表示)。

一.計數排序

演算法思想:給定n個位於0–k之間的數(k是乙個不太大的整數),我們可以統計出每個數前面有多少個小於它的數,然後就可以直接確定這個數在陣列中的位置了;比如說x前面有17個數,那麼x就應該放到18號位置上去,當然如果有多個相同的元素我們不能需要將它們都放到乙個位置上去,需要做些改變。時間複雜度:o(n+k)

**如下:

#include

#include

#include

using namespace std;

#define maxn 10000

///計數排序不是通過比較進行的排序,因而效率比較高

///但是只能對小範圍的正整數進行排序

void countingsort(int *a,int n)

這樣也能得到結果,但這樣其實是不穩定的排序方法。

*/for(int i=1;i<=k;i++)

c[i]=c[i]+c[i-1]; ///統計不小於i的數的個數

for(int i=n;i>=1;i--) ///從後往前是為了使得排序穩定

for(int i=1;i<=n;i++)

a[i]=b[i]; ///將排序結果複製回原陣列

}int main()

二.基數排序

演算法思想:基數排序其實就是對n個d位的數進行排序,每個數的每一位都需要考慮。按照我們一般的想法,我們應該先按最高位進行排序,然後再按次高位進行排序。。。。但基數排序的思想與此相反,它先按照最低位進行一次排序,然後再按照第二位。。。。。最後是最高位,當然我們需要選擇一種合適的演算法來進行每次按位的排序。

偽**如下:

radixsort(a,d)

for(int i=1;i<=d)

do use a stable sort

tosort array a on

digit

it

三.桶排序

桶排序處理的是輸入元素均勻的落在[0,1)區間之間的情況。其思想就是將區間[0,1)劃分成n個同樣大小的區間,或稱為桶,然後對每個桶內的元素進行排序,然後就可以直接輸出了。因為輸入是均勻的,所以這些元素在這些桶內分布應該也是比較均勻的,不會出現很多元素落在某個桶內的情況,所以有比較高的效率。

桶我們採用鍊錶實現;對於元素a[i],我們將它放到編號為floor(na[i])的桶內,桶的內部的排序我們可以採用插入排序。

演算法偽**如下:

bucketsort(a)

四.各種排序演算法穩定性終結

為什麼要提出穩定性這個概念?因為在實際中我們一般是按記錄中的某個關鍵值對一組記錄進行排序,比如說某組記錄含有身高,體重,年齡三個量,然後我們需要對其按年齡進行排序。這時我們希望如果關鍵值相等的時候,先輸入的資料應該還是排在前面,而不是隨便排。那麼前面我們學習的排序演算法那些是穩定的,那些是不穩定的呢?

我們先給出乙個總的結論,然後再來依次簡要說明一下:

穩定的排序演算法有: 插入排序,合併排序,計數排序,基數排序。

不穩定的排序演算法有:堆排序,快速排序。

1.插入排序

對於插入排序,相同的元素在前面插入的也總是排在前面,所以肯定是穩定的

2.合併排序

對於合併排序,我們重點分析它的合併過程;在合併左右過程只要我們保證在比較的時候如果兩個元素大小相同,我們就把座標小的放到前面就可以保證演算法是穩定的了。

3.堆排序

無論是建堆還是堆排序的過程都是不斷調整的過程,考慮節點i ,和i+1有相同的子節點,然後某次調整的時候節點i+1的子節點往上調整了而i的子節點沒有調整;這種情況說明堆排序是不穩定的。

4.快速排序

快排的交換發生在劃分的時候,有一種不穩定的情況就是把關鍵元素(key)交換到中間時會使得它和後面一段元素的相對順序被打亂;所以快排也是不穩定的

5.計數排序

計數排序最後確定每個數的位置時,是從後往前確定的,所以可以保證相同的元素,原來在後面的排序以後還是在後面;所以計數排序是穩定的。

6.基數排序

如果基數排序在按每一位進行排序時選擇的是乙個穩定的排序方法,那麼它也是穩定的。

計數排序(線性時間排序) 演算法導論

之前的排序都是通過比較得到的,即比較排序 在排序的最終結果中,各元素的次序依賴與它們之間的比較。而時間複雜度最好的也是o nlgn 接下來說乙個未經比較的排序,而複雜度則是線性的。計數排序 假設n個輸入元素的每乙個都是在0 k區間內的乙個整數,其中k為某個整數。當k o n 時,排序的執行時間為o ...

演算法導論系列筆記之線性時間排序

速度取決於計算模型 哪些操作是被允許的 在模型中只能進行兩兩之間的大小比較來決定順序 比較排序的演算法速度不會超過nlgn 決策樹 決策樹模型 證明確定性演算法 它執行的每一步都是完全正確的 偽 counting sort a,b,k let c 0 k be a new array 記錄各個數出現...

演算法導論 第8章 線性時間排序 計數排序

計數排序 n個元素都是0到k範圍得整數,當k o n 時,排序執行時間為o n 思想 對於數x,確定小於x的個數m,將x放在第m 1個位置上 例子 假設3個元素小於x,那麼x應該放在4上 輸入第一行的第乙個數n是陣列的個數,第一行第二個數表示所有n的元素中最大的數k 接下來的第二行就是n個數字 輸入...