Radix Sort: Hiểu về thuật toán sắp xếp theo Cơ Số

5 min read

Radix Sort là một thuật toán sắp xếp không so sánh được sử dụng để sắp xếp các số nguyên. Nó hoạt động dựa trên việc sắp xếp từng chữ số của các số nguyên theo thứ tự từ bé đến lớn hoặc từ lớn đến bé. Thuật toán này dựa trên một chiến lược phân chia, sắp xếp và kết hợp để đạt được kết quả cuối cùng.

1. Cách hoạt động của Radix Sort

Đầu tiên ta cho ví dụ mảng như: array[] = [170, 45, 75, 90, 802, 24, 2, 66]

Thuật toán sắp xếp cơ số hoạt động như thế nào | Bước 1

Bước 1: Tìm phần tử lớn nhất trong mảng là 802. Nó có ba chữ số nên chúng ta sẽ lặp ba lần, một lần cho mỗi vị trí quan trọng.

Bước 2: Sắp xếp các phần tử theo chữ số hàng đơn vị (X=0). Chúng tôi sử dụng kỹ thuật sắp xếp ổn định, chẳng hạn như sắp xếp đếm, để sắp xếp các chữ số ở mỗi vị trí quan trọng.

Sắp xếp theo vị trí đơn vị:

  • Thực hiện sắp xếp đếm trên mảng dựa trên các chữ số ở vị trí đơn vị.
  • Mảng được sắp xếp dựa trên vị trí đơn vị là [170, 90, 802, 2, 24, 45, 75, 66].
Thuật toán sắp xếp cơ số hoạt động như thế nào | Bước 2

Bước 3: Sắp xếp các phần tử theo chữ số hàng chục.

Sắp xếp theo hàng chục:

  • Thực hiện sắp xếp đếm trên mảng dựa trên các chữ số hàng chục.
  • Mảng được sắp xếp dựa trên vị trí hàng chục là [802, 2, 24, 45, 66, 170, 75, 90].
Thuật toán sắp xếp cơ số hoạt động như thế nào | Bước 3

Bước 4: Sắp xếp các phần tử theo chữ số hàng trăm.

Sắp xếp theo hàng trăm:

  • Thực hiện sắp xếp đếm trên mảng dựa trên các chữ số hàng trăm.
  • Mảng được sắp xếp dựa trên vị trí hàng trăm là [2, 24, 45, 66, 75, 90, 170, 802].
Thuật toán sắp xếp cơ số hoạt động như thế nào | Bước 4

Bước 5: Bây giờ mảng đã được sắp xếp theo thứ tự tăng dần.

Mảng được sắp xếp cuối cùng bằng cách sử dụng sắp xếp cơ số là [2, 24, 45, 66, 75, 90, 170, 802].

Thuật toán sắp xếp cơ số hoạt động như thế nào | Bước 5

2. Code thuật toán Radix Sort

// Hàm để lấy chữ số thứ d trong số nguyên n (tính từ phải sang trái)
function getDigit(num, d) {
    return Math.floor(Math.abs(num) / Math.pow(10, d)) % 10;
}

// Hàm để lấy số lớn nhất trong một mảng
function getMax(arr) {
    let max = 0;
    for (let num of arr) {
        max = Math.max(max, num);
    }
    return max;
}

// Hàm Radix Sort
function radixSort(arr) {
    const maxDigitCount = Math.floor(Math.log10(getMax(arr))) + 1; // Số chữ số lớn nhất trong mảng
    for (let k = 0; k < maxDigitCount; k++) {
        let digitBuckets = Array.from({ length: 10 }, () => []); // Mảng các thùng (buckets) để phân chia các số
        for (let i = 0; i < arr.length; i++) {
            const digit = getDigit(arr[i], k); // Lấy chữ số thứ k của số thứ i
            digitBuckets[digit].push(arr[i]); // Đưa số thứ i vào thùng tương ứng
        }
        arr = [].concat(...digitBuckets); // Kết hợp các thùng lại thành một mảng mới
    }
    return arr;
}

// Sử dụng Radix Sort để sắp xếp một mảng các số nguyên
let arr = [170, 45, 75, 90, 802, 24, 2, 66];
console.log("Mảng trước khi sắp xếp:", arr);
arr = radixSort(arr);
console.log("Mảng sau khi sắp xếp:", arr);

3. Phân tích độ phức tạp của thuật toán

Độ phức tạp về thời gian: 

  • Sắp xếp cơ số là một thuật toán sắp xếp số nguyên không so sánh, sắp xếp dữ liệu bằng các khóa số nguyên bằng cách nhóm các khóa theo các chữ số riêng lẻ có cùng vị trí và giá trị quan trọng. Nó có độ phức tạp về thời gian là O(d * (n + b)) , trong đó d là số chữ số, n là số phần tử và b là cơ sở của hệ thống số đang được sử dụng.
  • Trong triển khai thực tế, sắp xếp cơ số thường nhanh hơn các thuật toán sắp xếp dựa trên so sánh khác, chẳng hạn như sắp xếp nhanh hoặc sắp xếp hợp nhất, đối với các tập dữ liệu lớn, đặc biệt khi các khóa có nhiều chữ số. Tuy nhiên, độ phức tạp về thời gian của nó tăng tuyến tính theo số chữ số và do đó nó không hiệu quả đối với các tập dữ liệu nhỏ.

Không gian phụ trợ: 

  • Sắp xếp cơ số cũng có độ phức tạp về không gian là O(n + b), trong đó n là số phần tử và b là cơ số của hệ thống số. Sự phức tạp về không gian này xuất phát từ nhu cầu tạo các nhóm cho mỗi giá trị chữ số và sao chép các phần tử trở lại mảng ban đầu sau khi mỗi chữ số đã được sắp xếp.

4. Ưu và nhược điểm của thuật toán

4.1 Ưu điểm của thuật toán

  • Hiệu suất tốt với các số nguyên dương: Radix Sort hoạt động tốt với các số nguyên dương và không cần phải so sánh giữa các phần tử.
  • Dễ dàng cài đặt: Thuật toán này có thể dễ dàng cài đặt và hiểu.
  • Ổn định: Nếu sử dụng một thuật toán sắp xếp ổn định trong mỗi bước, Radix Sort sẽ cũng là một thuật toán ổn định.

4.2 Nhược điểm

  • Chỉ hoạt động với số nguyên không âm: Radix Sort không thích hợp cho các số nguyên âm nếu không có xử lý đặc biệt.
  • Không hiệu quả với các số lớn có phạm vi lớn: Nếu phạm vi của số lớn, Radix Sort có thể trở nên không hiệu quả vì số lượng thùng cần phải tạo ra có thể rất lớn.
  • Không phù hợp với các tập dữ liệu không có phân phối đồng đều: Nếu dữ liệu không phân phối đều, các thùng có thể có kích thước lớn khác nhau, làm giảm hiệu suất của thuật toán.

5. Kết luận

Radix Sort là một thuật toán sắp xếp mạnh mẽ cho các số nguyên không âm. Dựa vào cơ chế phân chia và sắp xếp từng chữ số, nó đạt được hiệu suất tốt trong một số trường hợp nhất định. Tuy nhiên, cần phải xem xét kỹ lưỡng các điều kiện đặc biệt của dữ liệu trước khi quyết định sử dụng Radix Sort cho một bài toán cụ thể.

Reference: https://www.geeksforgeeks.org/radix-sort/

Avatar photo

Clean Code: Nguyên tắc viết hàm trong lập trình…

Trong quá trình phát triển phần mềm, việc viết mã nguồn dễ đọc, dễ hiểu là yếu tố then chốt để đảm bảo code...
Avatar photo Dat Tran Thanh
3 min read

Clean Code: Nguyên tắc comment trong lập trình

Trong lập trình, code không chỉ là một tập hợp các câu lệnh để máy tính thực thi, mà còn là một hình thức...
Avatar photo Dat Tran Thanh
3 min read

Clean Code: Nguyên tắc xử lý lỗi (Error Handling)

Trong quá trình phát triển phần mềm, việc xử lý lỗi không chỉ là một phần quan trọng mà còn ảnh hưởng trực tiếp...
Avatar photo Dat Tran Thanh
4 min read

Leave a Reply

Your email address will not be published. Required fields are marked *