1.計數排序
git
顧名思義,是對待排序數組中的數據進行統計,而後根據統計的數據進行排序,例如:數組
待排序數組:ide
a[] = { 100, 123, 112, 123, 201, 123, 112, 156, 156, 178, 185, 156, 123, 112 }spa
首先取出數組中最大值與最小值(這個不用說了吧)3d
最大值:201 最小值:100orm
所以該數組的數值範圍爲 201 - 100 + 1 = 102blog
開闢一個大小爲102的數組 count[102] 並將全部元素初始化爲0排序
再次遍歷數組,以 a[ i - 100 ] 做爲數組count的下標,對該項進行加1it
獲得的count數組應該是(這裏count元素爲0的項就不出現了,太多了)io
count[ 0 ] = 1
count[ 12 ] = 3
count[ 23 ] = 4
count[ 56 ] = 3
count[ 78 ] = 1
count[ 85 ] = 1
count[ 101 ] = 1
其他的元素都爲0
此時遍歷count數組,將每一個元素對應寫回a數組,此時數組a應該爲
a = { 100,112,112,112,123,123,123,123,156,156,156,178,185,201 }
能夠看到,數組a已經排好了序。
代碼以下:
void CountSort(int* a, size_t n) //計數排序 { assert(a); int min = a[0]; int max = a[0]; for (int i = 1; i < n; ++i) { if (a[i] > max) max = a[i]; else if (a[i] < min) min = a[i]; } int countNum = max - min + 1; int* countArray = new int[countNum]; memset(countArray, 0, sizeof(int)*(countNum)); for (int i = 0; i < n; ++i) { ++countArray[a[i] - min]; } int index = 0; for (int i = 0; i < countNum; ++i) //寫回數組 { while (countArray[i]--) { a[index++] = i + min; } } delete[] countArray; }
能夠看到,計數排序有很大的侷限性,它適合對數據範圍相對比較集中的數據集合進行排序。
2.基數排序
咱們經過一個例子來看基數排序是怎樣進行排序的
設有一個初始序列爲: R {50, 123, 543, 187, 49, 30, 0, 2, 11, 100}
咱們知道,任何一個阿拉伯數,它的各個位數上的基數都是以0~9來表示的。
因此咱們不妨把0~9視爲10個桶。
咱們先根據序列的個位數的數字來進行分類,將其分到指定的桶中。例如:R[0] = 50,個位數上是0,將這個數存入編號爲0的桶中。
分類後,咱們在從各個桶中,將這些數按照從編號0到編號9的順序依次將全部數取出來。
這時,獲得的序列就是個位數上呈遞增趨勢的序列。
按照個位數排序: {50, 30, 0, 100, 11, 2, 123, 543, 187, 49}
接着按照十位進行如上排序(注意:沒有十位的數按照十位爲0處理)
按照十位數排序: {0, 100, 2, 11, 123, 30, 543, 49, 50, 187}
接着按照百位進行如上排序(注意:沒有百位的數按照百位爲0處理)
按照百位數排序: {0, 2, 11, 30, 49, 50, 100, 123, 187, 543}
排序完成
代碼以下:
int GetMaxBit(int* a, size_t n) //獲取數組中數字最多的位 { assert(a); int BitNum = 1; int tmpData = 10; for (int i = 0; i < n; ++i) { while (tmpData <= a[i]) { ++BitNum; tmpData *= 10; } } return BitNum; } void RadixSort(int* a, size_t n) //基數排序 { assert(a); int maxBit = GetMaxBit(a, n); int digit = 1; int* tmp = new int[n]; int countBit[10]; //計數 int startBit[10]; //起始位置 for (int i = 1; i <= maxBit; ++i) { memset(countBit, 0, sizeof(int)* 10); for (int i = 0; i < n; ++i) { int bit = (a[i]/digit)%10; //先各位,在十位百位…… ++countBit[bit]; } memset(startBit, 0, sizeof(int)* 10); startBit[0] = 0; for (int i = 1; i < 10; ++i) { startBit[i] = startBit[i - 1] + countBit[i - 1]; } for (int i = 0; i < n; ++i) //存入臨時數組 { int index = startBit[(a[i]/digit)%10]++; tmp[index] = a[i]; } for (int i = 0; i < n; ++i) //寫回原數組 { a[i] = tmp[i]; } digit *= 10; } delete[] tmp; }