数据结构中的基数排序算法
什么是基数排序算法?
基数排序是一种非比较排序算法。它的工作原理是将要排序的元素的各个数字分组。然后使用稳定的排序技术根据元素的基数来组织元素。它是一种线性排序算法。
排序过程涉及以下属性:
- 找到最大元素并获取该元素的位数。它为我们提供了排序过程将遵循的迭代次数。
- 在每次迭代中将元素的各个数字分组到相同的有效位置。
- 分组过程将从最低有效数字开始,到最高有效数字结束。
- 根据有效位置的数字对元素进行排序。
- 保持具有相同键值的元素的相对顺序。基数排序的这一特性使其成为一种稳定排序。
最后的迭代将给我们一个完全排序的列表。
基数排序算法的工作原理

让我们尝试使用基数排序算法按升序对上图中的整数列表进行排序。
以下是执行基数排序过程的步骤:
步骤1) 确定列表中具有最大值的元素。在本例中,该元素为 835。
步骤2) 计算最大元素的位数。835 正好有 3 位数字。
步骤3) 根据步骤2确定迭代次数。835有3位数字,这意味着迭代次数将为3。
步骤4) 确定元素的基数。由于这是十进制,因此基数为 10。
步骤5) 开始第一次迭代。
a)第一次迭代

在第一次迭代中,我们考虑每个元素的个位值。
步骤1) 对整数取 10 的模数,得到元素的个位。例如,623 取模 10 得到值 3,248 取模 10 得到值 8。
步骤2) 使用计数排序或任何其他稳定排序,根据整数的最低有效数字对其进行组织。如图所示,248 将落在第 8 个存储桶中。623 将落在第 3 个存储桶中,依此类推。
第一次迭代之后,列表现在如下所示。

从上图可以看出,列表尚未排序,需要更多迭代才能完全排序。
b)第二次迭代

在这次迭代中,我们将考虑 10 处的数字th 进行分类过程的地方。
步骤1) 将整数除以 10。248 除以 10 得到 24。
步骤2) 将步骤 1 的输出除以 10。24 除以 10 得到 4。
步骤3) 按照上一次迭代中的步骤 2 进行。
第二次迭代后,列表现在如下所示

从上图可以看出,列表仍未完全排序,因为它尚未按升序排列。
c)第三次迭代

对于最后一次迭代,我们希望获得最高有效位。在本例中,最高有效位是 100th 列表中每个整数的位置。
步骤1) 将整数除以 100...415 除以 100 得到 4。
步骤2) 将步骤 1 的结果除以 10。4 除以 10 再次得到 4。
步骤3) 按照上一次迭代中的步骤 3 进行。
我们可以看到,列表现在按升序排序。最后一次迭代已经完成,排序过程现已结束。
基数排序算法的伪代码
以下是基数排序算法的伪代码
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++ 实现基数排序的程序
#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);
}
输出:
162 248 415 623 835
Python 基数排序算法程序
#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)
输出:
[162,248,415,623,835]
基数排序的复杂度分析
有两种类型的复杂性需要考虑:空间复杂性和时间复杂性。
- 空间复杂度:O(n + b),其中 n 是数组的大小,b 是所考虑的基数。
- 时间复杂度:O(d*(n+b)),其中d是数组中最大元素的位数。
基数排序的空间复杂度
空间复杂性需要关注的两个特征
- 数组中元素的数量, n.
- 表示元素的基础, b.
有时这个底数可能大于数组的大小。
因此总体复杂度为 O(n+b)。
列表中元素的以下属性可能导致基数排序空间效率低下:
- 具有大量数字的元素。
- 元素的基数很大,如 64 位数字。
基数排序的时间复杂度
您可以将计数排序用作子程序,因为每次迭代都将式中 O(n+b) 时间。如果存在 d 次迭代,则总运行时间变为 o(d*(n+b))。 这里,“O”表示复杂度函数。
基数排序的线性
当满足以下条件时,基数排序是线性的:
- d 是常数,其中 d 是最大元素的位数。
- b 并不比 n.
基数排序与其他比较算法的比较
正如我们所见,Radix 排序的复杂度取决于字或数字的大小。在平均和最佳情况下,它的复杂度相同。即 O(d*(n+b))。此外,根据您在中间使用的排序技术,它也会有所不同。例如,您可以在 Radix 排序中使用计数排序或快速排序作为中间排序算法。
基数排序算法的应用
基数排序的重要应用是:
- 基数排序可用作使用大范围值的位置查找算法。
- 它用于构建DC3算法中的后缀数组。
- 它用于典型计算机中按顺序随机存取的机器中,对记录进行键入。
