Susun Radix di Jawa

1. Pengenalan

Dalam tutorial ini, kita akan belajar mengenai Radix Sort, menganalisis prestasinya, dan melihat pelaksanaannya.

Di sini kita memberi tumpuan untuk menggunakan Radix Sort untuk menyusun bilangan bulat, tetapi ia tidak terhad kepada angka sahaja. Kita boleh menggunakannya untuk menyusun jenis lain seperti String juga.

Untuk mempermudahnya, kita akan memfokuskan pada sistem perpuluhan di mana angka dinyatakan dalam asas (radix) 10.

2. Tinjauan Algoritma

Radix sort adalah algoritma penyortiran yang menyusun nombor berdasarkan kedudukan digit mereka. Pada asasnya, ia menggunakan nilai tempat digit dalam nombor. Tidak seperti kebanyakan algoritma penyortiran lain, seperti Merge Sort, Insertion Sort, Bubble Sort, ini tidak membandingkan nombor.

Urutan Radix menggunakan algoritma penyortiran stabil sebagai subrutin untuk menyusun digit. Kami telah menggunakan variasi pengiraan semacam sebagai subrutin di sini yang menggunakan radix untuk menyusun digit di setiap kedudukan. Pengiraan mengira adalah algoritma penyusun yang stabil dan ia berfungsi dengan baik dalam praktik.

Radix sort berfungsi dengan menyusun digit dari Least Significant Digit (LSD) ke Digit Significant (MSD). Kami juga dapat mengimplementasikan sort Radix untuk memproses digit dari MSD.

3. Contoh Pantas

Mari lihat bagaimana ia berfungsi dengan contoh. Mari pertimbangkan susunan berikut:

Pengulangan 1:

Kami akan menyusun susunan ini dengan memproses digit dari LSD dan bergerak ke arah MSD.

Oleh itu, mari kita mulakan dengan angka di satu tempat:

Selepas lelaran pertama, susunan kini kelihatan seperti:

Perhatikan bahawa nombor telah disusun mengikut digit di satu tempat.

Pengulangan 2:

Mari beralih ke angka di puluhan tempat:

Kini susunannya seperti:

Kami melihat bahawa nombor 7 telah menduduki posisi pertama dalam array kerana ia tidak mempunyai angka di tempat berpuluh. Kita juga boleh menganggap ini sebagai 0 di tempat berpuluh.

Pengulangan 3:

Mari beralih ke angka dalam kedudukan beratus:

Selepas lelaran ini, susunannya kelihatan seperti:

Dan algoritma berhenti di sini, dengan semua elemen disusun.

4. Pelaksanaan

Sekarang mari kita lihat pelaksanaannya.

void sort(int[] numbers) { int maximumNumber = findMaximumNumberIn(numbers); int numberOfDigits = calculateNumberOfDigitsIn(maximumNumber); int placeValue = 1; while (numberOfDigits-- > 0) { applyCountingSortOn(numbers, placeValue); placeValue *= 10; } }

Algoritma berfungsi dengan mencari bilangan maksimum dalam array dan kemudian mengira panjangnya. Langkah ini membantu kita memastikan bahawa kita melaksanakan subrutin untuk setiap nilai tempat.

Sebagai contoh, dalam susunan, [7, 37, 68, 123, 134, 221, 387, 468, 769] , bilangan maksimum ialah 769 dan panjangnya ialah 3.

Oleh itu, kita mengulangi dan menggunakan subrutin tiga kali pada digit di setiap kedudukan:

void applyCountingSortOn(int[] numbers, int placeValue) { int range = 10 // decimal system, numbers from 0-9 // ... // calculate the frequency of digits for (int i = 0; i < length; i++) { int digit = (numbers[i] / placeValue) % range; frequency[digit]++; } for (int i = 1; i 
    
     = 0; i--) { int digit = (numbers[i] / placeValue) % range; sortedValues[frequency[digit] - 1] = numbers[i]; frequency[digit]--; } System.arraycopy(result, 0, numbers, 0, length); }
    

Dalam subrutin, kami telah menggunakan radix (range) untuk menghitung kejadian setiap digit dan meningkatkan frekuensi. Jadi, setiap tong dalam julat dari 0 hingga 9 akan mempunyai beberapa nilai berdasarkan kekerapan digit. Kami kemudian menggunakan frekuensi untuk meletakkan setiap elemen dalam array. Ini juga membantu kita untuk meminimumkan ruang yang diperlukan untuk menyusun susunan.

Sekarang mari kita menguji kaedah kami:

@Test public void givenUnsortedArray_whenRadixSort_thenArraySorted() { int[] numbers = {387, 468, 134, 123, 68, 221, 769, 37, 7}; RadixSort.sort(numbers); int[] numbersSorted = {7, 37, 68, 123, 134, 221, 387, 468, 769}; assertArrayEquals(numbersSorted, numbers); }

5. Radix Sort vs Counting Sort

Dalam subrutin, panjang array frekuensi adalah 10 (0-9). Dalam kes Pengiraan Mengira, kami tidak menggunakan jarak . Panjang array frekuensi akan menjadi bilangan maksimum dalam array + 1. Oleh itu, kami tidak membaginya menjadi tong sedangkan Radix Sort menggunakan tong sampah untuk menyusun.

Mengira Sort cukup efisien apabila panjang array tidak jauh lebih kecil daripada nilai maksimum dalam array sedangkan Radix Sort memungkinkan untuk nilai yang lebih besar dalam array.

6. Kerumitan

Prestasi Radix Sort bergantung pada algoritma penyusun stabil yang dipilih untuk menyusun digit.

Di sini kami telah menggunakan Radix Sort untuk menyusun susunan nombor n di pangkalan b . Dalam kes kami, asasnya adalah 10. Kami telah mengira Hitung Pengiraan d kali di mana d bermaksud bilangan digit. Jadi kerumitan masa Radix Sort menjadi O (d * (n + b)) .

Kerumitan ruang adalah O (n + b) kerana kami telah menggunakan variasi Counting Sort sebagai subrutin di sini.

7. Kesimpulannya

Dalam artikel ini, kami menerangkan algoritma pengisaran Radix dan menggambarkan cara melaksanakannya.

Seperti biasa, pelaksanaan kod tersedia di Github.