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