Thuật toán sắp xếp cơ số trong cấu trúc dữ liệu

Thuật toán sắp xếp cơ số là gì?

Radix Sort là một thuật toán sắp xếp không so sánh. Nó hoạt động bằng cách nhóm các chữ số riêng lẻ của các phần tử cần sắp xếp. Sau đó, một kỹ thuật sắp xếp ổn định được sử dụng để sắp xếp các phần tử dựa trên cơ số của chúng. Đó là một thuật toán sắp xếp tuyến tính.

Quá trình phân loại bao gồm các tính chất sau:

  • Tìm phần tử lớn nhất và lấy số chữ số của phần tử đó. Nó cho chúng ta số lần lặp mà quá trình sắp xếp sẽ tuân theo.
  • Nhóm các chữ số riêng lẻ của các phần tử ở cùng một vị trí quan trọng trong mỗi lần lặp.
  • Quá trình nhóm sẽ bắt đầu từ chữ số có nghĩa nhỏ nhất và kết thúc ở chữ số có nghĩa nhất.
  • Sắp xếp các phần tử dựa trên các chữ số tại vị trí quan trọng đó.
  • Duy trì thứ tự tương đối của các phần tử có cùng giá trị khóa. Thuộc tính này của sắp xếp cơ số làm cho nó trở thành một sắp xếp ổn định.

Lần lặp cuối cùng sẽ cho chúng ta một danh sách được sắp xếp hoàn chỉnh.

Hoạt động của thuật toán sắp xếp cơ số

Hoạt động của thuật toán sắp xếp cơ số
Danh sách các số nguyên cần sắp xếp

Hãy thử sắp xếp danh sách các số nguyên trong hình trên theo thứ tự tăng dần bằng thuật toán Radix Sort.

Dưới đây là các bước để thực hiện quy trình Sắp xếp Cơ số:

Bước 1) Xác định phần tử có giá trị lớn nhất trong danh sách. Trong trường hợp này, nó là 835.

Bước 2) Tính số chữ số của phần tử lớn nhất. 835 có đúng 3 chữ số.

Bước 3) Xác định số lần lặp dựa vào bước 2. 835 có 3 chữ số, nghĩa là số lần lặp sẽ là 3.

Bước 4) Xác định cơ sở của các phần tử. Vì đây là hệ thập phân nên cơ số sẽ là 10.

Bước 5) Bắt đầu lần lặp đầu tiên.

a) Lần lặp đầu tiên

Hoạt động của thuật toán sắp xếp cơ số
Sắp xếp theo chữ số cuối cùng

Trong lần lặp đầu tiên, chúng tôi xem xét giá trị vị trí đơn vị của từng phần tử.

Bước 1) Sửa số nguyên thêm 10 để lấy vị trí đơn vị của các phần tử. Ví dụ: 623 mod 10 cho chúng ta giá trị 3 và 248 mod 10 cho chúng ta giá trị 8.

Bước 2) Sử dụng phương pháp sắp xếp đếm hoặc bất kỳ phương pháp sắp xếp ổn định nào khác để sắp xếp các số nguyên theo chữ số có nghĩa nhỏ nhất của chúng. Như đã thấy Từ hình vẽ, 248 sẽ rơi vào thùng thứ 8. 623 sẽ rơi vào thùng thứ 3, v.v.

Sau lần lặp đầu tiên, danh sách bây giờ trông như thế này.

Hoạt động của thuật toán sắp xếp cơ số
Danh sách sau lần lặp đầu tiên

Như bạn có thể thấy trong hình trên, danh sách chưa được sắp xếp và cần phải lặp lại nhiều lần để được sắp xếp đầy đủ.

b) Lần lặp thứ hai

Hoạt động của thuật toán sắp xếp cơ số
Sắp xếp dựa trên chữ số hàng chục

Trong lần lặp này, chúng ta sẽ xem xét chữ số ở số 10th nơi thực hiện quá trình phân loại.

Bước 1) Chia các số nguyên cho 10. 248 chia cho 10 được 24.

Bước 2) Sửa đổi đầu ra của bước 1 x 10. 24 mod 10 cho chúng ta 4.

Bước 3) Thực hiện theo bước 2 từ lần lặp trước.

Sau lần lặp thứ hai, danh sách bây giờ trông như thế này

Hoạt động của thuật toán sắp xếp cơ số
Danh sách sau lần lặp thứ hai

Bạn có thể thấy từ hình trên rằng danh sách vẫn chưa được sắp xếp hoàn toàn vì nó chưa theo thứ tự tăng dần.

c) Lần lặp thứ ba

Hoạt động của thuật toán sắp xếp cơ số
Sắp xếp dựa trên các chữ số ở hàng trăm vị trí

Đối với lần lặp cuối cùng, chúng tôi muốn lấy chữ số có ý nghĩa nhất. Trong trường hợp này là 100th vị trí cho mỗi số nguyên trong danh sách.

Bước 1) Chia các số nguyên cho 100… 415 chia cho 100 được 4.

Bước 2) Sửa đổi kết quả từ bước 1 đến 10. 4 mod 10 lại cho chúng ta 4.

Bước 3) Thực hiện theo bước 3 từ lần lặp trước.

Hoạt động của thuật toán sắp xếp cơ số
Danh sách sau lần lặp thứ ba

Như chúng ta có thể thấy, danh sách hiện được sắp xếp theo thứ tự tăng dần. Lần lặp cuối cùng đã được hoàn thành và quá trình sắp xếp đã kết thúc.

Mã giả của thuật toán sắp xếp cơ số

Đây là mã giả cho Thuật toán sắp xếp cơ số

radixSortAlgo(arr as an array)
  Find the largest element in arr
  maximum=the element in arr that is the largest
  Find the number of digits in maximum
  k=the number of digits in maximum 
  Create buckets of size 0-9 k times
for j -> 0 to k
  Acquire the jth place of each element in arr. Here j=0 represents the least significant digit.
  Use a stable sorting algorithm like counting sort to sort the elements in arr according to the digits of the elements in the jthplace
   arr = sorted elements

C++ Chương trình thực hiện sắp xếp cơ số

#include <iostream>
using namespace std;
// Function to get the largest element in an array
int getMaximum(int arr[], int n) {
  int maximum = arr[0];
  for (int i = 1; i < n; i++) {
    if (maximum < arr[i]) maximum = arr[i];
  }
  return maximum;
}
// We are using counting sort to sort the elements digit by digit
void countingSortAlgo(int arr[], int size, int position) {
  const int limit = 10;
  int result[size];
  int count[limit] = {0};
  // Calculating the count of each integers
  for (int j = 0; j < size; j++) count[(arr[j] / position) % 10]++;
  // Calculating the cumulative count
  for (int j = 1; j < limit; j++) {
    count[j] += count[j - 1];
  }
  // Sort the integers
  for (int j = size - 1; j >= 0; j--) {
    result[count[(arr[j] / position) % 10] - 1] = arr[j];
    count[(arr[j] / position) % 10]--;
  }
  for (int i = 0; i < size; i++) arr[i] = result[i];
}
// The radixSort algorithm
void radixSortAlgo(int arr[], int size) {
  // Get the largest element in the array
  int maximum = getMaximum(arr, size);
  for (int position = 1; maximum / position > 0; position *= 10)
    countingSortAlgo(arr, size, position);
}
// Printing final result
void printResult(int arr[], int size) {
  for (int i = 0; i < size; i++) {
    cout << arr[i] << " ";
  }
  cout << endl;
}
int main() {
  int arr[] = {162, 623, 835, 415, 248};
  int size = sizeof(arr) / sizeof(arr[0]);
  radixSortAlgo(arr, size);
  printResult(arr, size);
}

Đầu ra:

162 248 415 623 835

Python Chương trình cho thuật toán sắp xếp cơ số

#Radix Sort using python
def countingSortAlgo(arr, position):
    n = len(arr)
    result = [0] * n
    count = [0] * 10  # Calculating the count of elements in the array arr
    for j in range(0, n):
        element = arr[j] // position
        count[element % 10] += 1  # Calculating the cumulative count
    for j in range(1, 10):
        count[j] += count[j - 1]  # Sorting the elements
    i = n - 1
    while i >= 0:
        element = arr[i] // position
        result[count[element % 10] - 1] = arr[i]
        count[element % 10] -= 1
        i -= 1
    for j in range(0, n):
        arr[j] = result[j]


def radixSortAlgo(arr):  # Acquiring the largest element in the array
    maximum = max(arr)  # Using counting sort to sort digit by digit
    position = 1
    while maximum // position > 0:
        countingSortAlgo(arr, position)
        position *= 10


input = [162, 623, 835, 415, 248]
radixSortAlgo(input)
print(input)

Đầu ra:

[162,248,415,623,835]

Phân tích độ phức tạp của Radix Sort

Có hai loại độ phức tạp cần xem xét: độ phức tạp về không gian và độ phức tạp về thời gian.

  • Độ phức tạp về không gian: O(n+b) trong đó n là kích thước của mảng và b là cơ sở được xem xét.
  • Độ phức tạp thời gian: O(d*(n+b)) trong đó d là số chữ số của phần tử lớn nhất trong mảng.

Độ phức tạp không gian của thuật toán sắp xếp theo cơ số

Hai tính năng cần tập trung vào để có không gian phức tạp

  • Số phần tử trong mảng, n.
  • Cơ sở biểu diễn các phần tử b.

Đôi khi cơ sở này có thể lớn hơn kích thước của mảng.

Do đó, độ phức tạp tổng thể là O(n+b).

Các thuộc tính sau đây của các phần tử trong danh sách có thể làm cho không gian sắp xếp cơ số trở nên kém hiệu quả:

  • Các phần tử có số lượng chữ số lớn.
  • Cơ sở của các phần tử lớn, giống như số 64 bit.

Độ phức tạp thời gian của thuật toán sắp xếp theo cơ số

Bạn có thể sử dụng tính năng sắp xếp đếm như một chương trình con vì mỗi lần lặp sẽ mấte O(n+b) thời gian. Nếu tồn tại d lần lặp, tổng thời gian chạy sẽ trở thành O(d*(n+b)). Ở đây, “O” có nghĩa là hàm phức tạp.

Độ tuyến tính của sắp xếp cơ số

Sắp xếp cơ số là tuyến tính khi

  • d là hằng số, trong đó d là số chữ số của phần tử lớn nhất.
  • b không lớn hơn nhiều so với n.

So sánh Radix Sort với các thuật toán so sánh khác

Như chúng ta đã thấy, độ phức tạp của Radix sort dựa trên kích thước của một từ hoặc số. Nó sẽ có cùng độ phức tạp đối với trường hợp trung bình và trường hợp tốt nhất. Và đó là O(d*(n+b)). Ngoài ra, nó khác nhau tùy theo kỹ thuật sắp xếp mà bạn sử dụng ở giữa. Ví dụ, bạn có thể sử dụng sắp xếp đếm hoặc sắp xếp nhanh cho thuật toán sắp xếp trung gian bên trong Radix sort.

Ứng dụng của thuật toán sắp xếp cơ số

Các ứng dụng quan trọng của Radix Sort là:

  • Sắp xếp cơ số có thể được sử dụng làm thuật toán tìm vị trí trong đó sử dụng phạm vi giá trị lớn.
  • Nó được sử dụng để xây dựng một mảng hậu tố trong thuật toán DC3.
  • Nó được sử dụng trong máy truy cập ngẫu nhiên, tuần tự có trong một máy tính thông thường nơi các bản ghi được khóa.