1. 程式人生 > 實用技巧 >Codeforces Round #177 (Div. 2) B. Polo the Penguin and Matrix (貪心,數學)

Codeforces Round #177 (Div. 2) B. Polo the Penguin and Matrix (貪心,數學)

基數排序(桶排序的一種)介紹

1)基數排序(radix sort)屬於“分配式排序”(distribution sort),又稱“桶子法”(bucket sort)或 bin sort,顧名思義,它是通過鍵值的各個位的值,將要排序的元素分配至某些“桶”中,達到排序的作用
2)基數排序法是屬於穩定性的排序,基數排序法的是效率高的穩定性排序法
3)基數排序(Radix Sort)是桶排序的擴充套件
4)基數排序是 1887 年赫爾曼·何樂禮發明的。它是這樣實現的:將整數按位數切割成不同的數字,然後按每個位數分別比較。

基數排序基本思想

  • 將所有待比較數值統一為同樣的數位長度,數位較短的數前面補零。
  • 然後,從最低位開始,依次進行一次排序。 這樣從最低位排序一直到最高位排序完成以後, 數列就變成一個有序序列。

基數排序圖文說明

將陣列 {53, 3, 542, 748, 14, 214} 使用基數排序, 進行升序排序

基數排序的說明

1) 基數排序是對傳統桶排序的擴充套件,速度很快.
2) 基數排序是經典的空間換時間的方式,佔用記憶體很大, 當對海量資料排序時,容易造成 OutOfMemoryError 。
3) 基數排序是穩定的。[注:假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些 記錄的相對次序保持不變,即在原序列中,r[i]=r[j],且 r[i]在 r[j]之前,而在排序後的序列中,r[i]仍在 r[j]之前,則稱這種排序演算法是穩定的;否則稱為不穩定的]


4) 有負數的陣列,我們不用基數排序來進行排序, 如果要支援負數,參考: https://code.i-harness.com/zh-CN/q/e98fa9

程式碼實現

1. publicclassradixsort{
2. publicstaticvoidmain(String[]args){
3. int[]arr={110,4771,121,74,1,30,7,28,64};
4. System.out.println("原陣列為:"+Arrays.toString(arr));
5. radixSort(arr);
6. System.out.println("排序後陣列為:"+Arrays.toString(arr));
7. } 8. 9. //基數排序方法 10. privatestaticvoidradixSort(int[]arr){ 11. //一、得到陣列中最大的數的位數 12. intmax=arr[0]; 13. for(intdata:arr){ 14. if(max<data){ 15. max=data; 16. } 17. } 18. Stringstrmax=String.valueOf(max); 19. intsize=strmax.toCharArray().length;//size即為陣列中最大的數的位數-->迴圈的次數 20. 21. //二、(針對每個元素的對應位進行排序處理),第一次是個位,第二次是十位,第三次是百位.. 22. for(intk=0,n=1;k<size;k++,n*=10){ 23. 24. //定義一個二維陣列,表示10個桶,每個桶就是一個一維陣列 25. //說明 26. //1.二維陣列包含10個一維陣列 27. //2.為了防止在放入數的時候,資料溢位,則每個一維陣列(桶),大小定為arr.length 28. //3.明確:基數排序是使用空間換時間的經典演算法 29. int[][]bucket=newint[10][arr.length]; 30. //為了記錄每個桶中,實際存放了多少個數據,我們定義一個一維陣列來記錄各個桶的每次放入的資料個數 31. //可以這裡理解 32. //比如:bucketElementCounts[0]=3,記錄的就是bucket[0]桶的放入資料個數為3 33. int[]bucketElementCounts=newint[10]; 34. 35. for(intvalue:arr){//將個位數值與序號相同的加入桶中 36. intdigitOfElement=value/n%10;//元素的個位數的值 37. bucket[digitOfElement][bucketElementCounts[digitOfElement]]=value; 38. bucketElementCounts[digitOfElement]++; 39. } 40. 41. //按照這個桶的順序(一維陣列的下標依次取出資料,放入原來陣列) 42. intindex=0; 43. for(inti=0;i<bucket.length;i++){//遍歷每一桶,並將桶中是資料,放入到原陣列 44. if(bucketElementCounts[i]!=0){//如果桶中,有資料,我們才放入到原陣列 45. for(intj=0;j<bucketElementCounts[i];j++){//迴圈該桶即第k個桶(即第k個一維陣列),放入 46. arr[index]=bucket[i][j]; 47. index++; 48. } 49. } 50. bucketElementCounts[i]=0;//第i+1輪處理後,需要將每個bucketElementCounts[k]=0!!不要忘記了!! 51. } 52. 53. } 54. } 55. }