計數排序和基數排序

2021-07-08 11:20:40 字數 2730 閱讀 9877

計數排序基數排序是屬於線性級時間複雜度的排序方式,雖然沒有冒泡,選擇,快排演算法那些讓人廣為所知,但是這兩種排序方式在某些場合非常適用。計數排序是基數排序的基礎,最為關鍵的是:基數排序演算法是字尾陣列的關鍵(當然字尾陣列也可以用快排),字尾陣列是用於處理字串的一種非常優秀的資料結構,可以高效的處理很多字串問題,比如重複子串,回文子串等等,這裡不討論字尾陣列的問題。

1、計數排序演算法

計數排序演算法的前提是:假設有n個輸入元素,且這些元素都是在0~k區間內的乙個整數。其演算法的思想就是 對於每乙個輸入的元素x,確定小於x的元素個數。利用這個資訊,就可以直接把x輸出到輸出陣列中的制定位置。例如,如果有10個元素小於x,那麼x就應該在第11的位置輸出。當然如果有多個元素相同時,輸出方案要做修改,因為不可能將這些元素輸出到相同的位置。 利用這一思想,寫出計數排序演算法的c++的實現:

/*計數排序演算法*/

#include using namespace std;

const int maxn = 1000;

const int k = 1000;

int a[maxn], c[maxn], b[maxn];

/*a陣列是待排序的陣列,b陣列是最終排好序的陣列

c陣列是用於統計每個元素大小關係的陣列,k表示待排序

陣列的上界,就是a陣列中不能有大於k的元素*/

int main() ;

//將c陣列清零

for(int i = 0; i < k;i++)

c[i] = 0;

/*統計a中所有元素出現的次數.如果輸入的元素是i,則c[i]的值就會

加1.值得注意的是在這裡c陣列的下標代表了輸入的元素,而c陣列的

值代表了元素的出現次數*/

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

c[a[i]]++;

/*這個迴圈的作用是通過加總計算確定對於每乙個i=0,1.....k有多少個元素是小於或者等於i的*/

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

c[i] += c[i-1];

/*如果所有元素都不相同,那麼對於每乙個a[i]來說,c[a[i]]肯定就是a[i]輸出的正確位置了,如果a中

有相同的元素,那麼我們將a[i]放入陣列b後,c[a[i]]必須減一才能保證相同元素不會重疊*/

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

b[--c[a[i]]] = a[i];

/*輸出拍好序的陣列*/

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

cout << b[i] << " ";

return 0;

2、基數排序演算法

當輸入的序列元素取值特別大的時候,計數排序演算法在效率和可行性上面將會崩潰,而基數排序則可以很好的解決這內大數值資料的問題。基數排序是基於對數的每一位進行比較。那麼是該從資料的高位開始比較還是低位開始比較?答案是從低位開始比較,這是因為越是排在後面位置的數字,對整個數的影響就越大,而最高有效位顯然比低位的資料對整個數的影響大。例如對123,312,245,531,進行基數排序,首先對各位數排序,結果是:531,312,123,245,第二次對十位數排序,結果是:312,123,531,245,最後一次對百位數排序,結果是:123,245,312,531.可以看到結果是對的。按照這樣的思想,寫出c++**的實現:

/*基數排序*/

#include using namespace std;

const int maxn = 1000;

const int k = 1000;

int a[maxn], c[maxn], b[maxn];

int main();

/*a中資料最多有3位,所以我們分為三段來處理,用變數t來

依次取出資料的各個位*/

for (int i = 0,t = 1;i < 3;i++,t*=10)

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

cout << a[i] << " ";

}

3、字串的排序

關於比較字串的大小,是按照字典順序進行比較的,對於字串a、b

首先從字串的起始位置開始比較,如果a[0] > b[0],則字串a>b,如果相等,則比較下一位,直到比較出結果。字串的比較在很多公司的筆試中都會看到,其特點就是按字典序給字串排序。基於字串這種比較的特點,用基數排序是比較合適的。

在這裡,用c++來實現的話就很方便,因為c++ 有string類,而且過載了》,<,==等運算子。但是其內部實現的話我覺得用基數排序是很好的(雖然我不知道庫裡面是不是這樣寫的)。在這裡就不用c來寫了,因為實現機制和上面的一樣,但是值得注意的是,字串的比較中我們同樣的從最低的位開始比較,這裡最低的位其實是從字串的最後乙個字元開始比較的。

用c++氣泡排序實現的字串比較

#include #include using namespace std;

int main();

int n = 6;

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

for (int j = 0; j < n - i - 1;j++)

if (str[j] > str[j+1])

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

cout <

計數排序 基數排序

一.計數排序 counting sort 基本思想 對每乙個輸入元素x,確定出小於x的元素個數。適用範圍 適用於輸入是由小範圍的整數構成的序列。穩定性 演算法是穩定的。具體實現 include using namespace std arr 初始輸入陣列,res 存放排序結果的陣列,hash臨時儲存...

桶排序 基數排序 計數基數排序 Java

前面已經講述了很多排序演算法,但是他們的排序演算法都是基於兩個值之間的比較,通過決策樹的方法可以證明深度為d的二叉樹則最多有 一些好的排序演算法是可以達到時間複雜度是線性的,桶排序就是其中一種。比如有n個數,但是這些數的最大數不超過m。這個時候就可以定義乙個含有m個元素的陣列 初始值為0 然後遍歷n...

計數排序 桶排序和基數排序

當輸入的元素是 n 個 0 到 k 之間的整數時,它的執行時間是 n k 計數排序不是比較排序,排序的速度快於任何比較排序演算法。由於用來計數的陣列c的長度取決於待排序陣列中資料的範圍 等於待排序陣列的最大值與最小值的差加上1 這使得計數排序對於資料範圍很大的陣列,需要大量時間和記憶體。例如 計數排...