基数排序(桶排序)
基數(shù)排序又叫桶排序:
先按照個位數(shù)排序,第一次排序好之后;再次按照十位數(shù)進行排序,第二次排序好之后;第三次對百位進行排序..................
實現(xiàn)原理圖:拿出一些個類似“桶”的東西 將分別按照個位,十位,百位排序好的放到這些“桶”中,然后按照從小到大,從上到下的規(guī)則開始取值
排序的次數(shù)是該數(shù)組中位數(shù)最多的元素來決定的 例如下圖中排序三次,最高位數(shù)是百
相同道理,如果位數(shù)最多元素是千的話,那就得排序四次!
?
?
?
如上所示,排序三次之后就完成了該數(shù)組的排序!每個桶大家可以想像成一個隊列,具有先進先出的特點!
下面進行代碼的實現(xiàn):
首先得求出數(shù)組中的最大位數(shù):
static int Get_Figure_Max(int arr[], int len) //獲取最大位數(shù)count
{int max = arr[0];for (int i = 1; i < len; i++){if (arr[i] > max){max = arr[i];}}int count = 0;while (max != 0){count++;max /= 10;}return count;
}
然后根據(jù)傳進來index值的不同分別求出個位 十位 百位這些位數(shù)上面的數(shù)值:
static int Get_Num(int n, int index) //假設(shè)傳進來(123,2) 傳出的值就是1 獲取這個數(shù)的百位數(shù)字
{ //index = 0 獲取個位數(shù)字的值 index = 1 獲取十位數(shù)字的值 以此類推for (int i = 0; i < index; i++){n = n / 10;}return n % 10;
}
然后就是根據(jù)位數(shù)個數(shù)和各種位數(shù)的數(shù)值進行排序的函數(shù):
static void Radix(int arr[], int len, int index) //index是位數(shù)
{int brr[10][20]; //代表0~9號桶 就是上圖中的長方形格子就是一個桶 十個桶就 十個數(shù)據(jù) 列少位給大點 所以就brr[10][20]int crr[10]; //用crr[i]來代表i號桶中有crr[i]個有效值for (int i = 0; i < len; i++){int tmp = Get_Num(arr[i],index); //tmp現(xiàn)在存放的就是arr[i]應(yīng)該放的桶號brr[tmp][crr[tmp]++] = arr[i]; //前面說過crr[i]代表i號桶中有crr[i]個有效值 // 那么crr[tmp]中就有著tmp號桶中有crr[tmp]個有效值//初始有效值都是0 有一個有效值就得++}int k = 0;for (int i = 0; i < len; i++) //二維數(shù)組 雙層for循環(huán){for (int j = 0; j < crr[i]; i++){arr[k++] = brr[i][j];}}
}
最后來個函數(shù)總成 調(diào)用上述函數(shù):
void Radix_Sort(int arr[], int len)
{int count = Get_Figure_Max(arr, len);for (int i = 0; i < count; i++){Radix(arr,len,i); //i = 0 以個位排序 i = 1 以十位排序 以此類推}
}
上述被調(diào)用的函數(shù)前面都有static ,這是因為函數(shù)調(diào)用函數(shù)一般不想被他人所見? static隱藏的作用
最后將函數(shù)寫在一起:
static int Get_Figure_Max(int arr[], int len) //獲取最大位數(shù)count
{int max = arr[0];for (int i = 1; i < len; i++){if (arr[i] > max){max = arr[i];}}int count = 0;while (max != 0){count++;max /= 10;}return count;
}static int Get_Num(int n, int index) //假設(shè)傳進來(123,2) 傳出的值就是1 獲取這個數(shù)的百位數(shù)字
{ //index = 0 獲取個位數(shù)字的值 index = 1 獲取十位數(shù)字的值 以此類推for (int i = 0; i < index; i++){n = n / 10;}return n % 10;
}static void Radix(int arr[], int len, int index) //index是位數(shù)
{int brr[10][20]; //代表0~9號桶 就是上圖中的長方形格子就是一個桶 十個桶就 十個數(shù)據(jù) 列少位給大點 所以就brr[10][20]int crr[10]; //用crr[i]來代表i號桶中有crr[i]個有效值for (int i = 0; i < len; i++){int tmp = Get_Num(arr[i],index); //tmp現(xiàn)在存放的就是arr[i]應(yīng)該放的桶號brr[tmp][crr[tmp]++] = arr[i]; //前面說過crr[i]代表i號桶中有crr[i]個有效值 // 那么crr[tmp]中就有著tmp號桶中有crr[tmp]個有效值//初始有效值都是0 有一個有效值就得++}int k = 0;for (int i = 0; i < len; i++) //二維數(shù)組 雙層for循環(huán){for (int j = 0; j < crr[i]; i++){arr[k++] = brr[i][j];}}
}void Radix_Sort(int arr[], int len)
{int count = Get_Figure_Max(arr, len);for (int i = 0; i < count; i++){Radix(arr,len,i); //i = 0 以個位排序 i = 1 以十位排序 以此類推}
}
這玩意思路不難理解,圖解也挺簡單,代碼寫起來還不是很簡單,主要就是二維數(shù)組brr[10][20]中桶中元素的下標crr[]那塊難以理解,因為剛開始crr都是零,所以每次使用完之后都得++一下!
總結(jié)
- 上一篇: 【C++】多线程(链式、循环队列)实现生
- 下一篇: Linux阶段复习题