基数排序(Radix Sort)是一种非比较性的排序算法,它将整数按位数逐个排序,每个位数的排序采用稳定的排序算法,最终得到有序序列。本文将详细介绍基数排序的工作原理,提供示例和Python、Go、Java以及C语言的实现代码。
基数排序的基本思想
基数排序的核心思想是将整数按位数切割成不同的数字,然后按每个位上的数字分组。具体步骤如下:
- 确定位数: 确定待排序整数的最大位数,作为排序的轮数。
- 按位分组: 将整数按位数分成个位、十位、百位等不同组,从最低位开始。
- 每个位上的排序: 对每个位上的数字进行稳定排序,可以选择计数排序等。
- 合并: 合并每个位上的数字,得到最终有序序列。
基数排序的示例
让我们通过一个示例来理解基数排序的工作原理。假设我们有一个整数数组 [170, 45, 75, 90, 802, 24, 2, 66],我们希望按升序排序它。
- 确定位数: 最大整数是802,有3位数字,因此需要3轮排序。
- 按位分组: 将整数按个位数字分组。
- 桶0: [170, 90]
- 桶1: [801]
- 桶2: [802, 2]
- 桶3: []
- 桶4: []
- 桶5: [75]
- 桶6: [66]
- 桶7: []
- 桶8: []
- 桶9: [45, 24]
- 每个位上的排序: 对每个位上的数字进行稳定排序,这里选择计数排序。
- 第一轮(个位): 170, 90, 801, 802, 2, 75, 66, 45, 24
- 第二轮(十位): 801, 802, 2, 24, 45, 66, 75, 170, 90
- 第三轮(百位): 2, 24, 45, 66, 75, 90, 170, 801, 802
- 合并: 得到最终有序序列。
- 排序后的数组: [2, 24, 45, 66, 75, 90, 170, 801, 802]
基数排序的时间复杂度
基数排序的时间复杂度取决于稳定排序算法的时间复杂度以及位数。假设n是待排序元素的数量,k是元素的位数,t是稳定排序算法的时间复杂度。
- 每位的排序时间: O(n + t)
- 总的排序时间: O(k * (n + t))
综合起来,基数排序的时间复杂度为O(k * (n + t))。
基数排序是一种稳定的排序算法,适用于整数排序。它在元素位数较小且范围确定的情况下表现出色。
示例代码
以下是基数排序的示例代码,分别使用Python、Go、Java和C语言编写。
Python 基数排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| def counting_sort(arr, exp): n = len(arr) output = [0] * n count = [0] * 10
for i in range(n): index = arr[i] // exp count[index % 10] += 1
for i in range(1, 10): count[i] += count[i - 1]
i = n - 1 while i >= 0: index = arr[i] // exp output[count[index % 10] - 1] = arr[i] count[index % 10] -= 1 i -= 1
for i in range(n): arr[i] = output[i]
def radix_sort(arr): max_num = max(arr) exp = 1
while max_num // exp > 0: counting_sort(arr, exp) exp *= 10
arr = [170, 45, 75, 90, 802, 24, 2, 66] radix_sort(arr) print("排序后的数组:", arr)
|
Go 基数排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| package main
import ( "fmt" )
func countingSort(arr []int, exp int) { n := len(arr) output := make([]int, n) count := make([]int, 10)
for i := 0; i < n; i++ { index := arr[i] / exp % 10 count[index]++ }
for i := 1; i < 10; i++ { count[i] += count[i-1] }
for i := n - 1; i >= 0; i-- { index := arr[i] / exp % 10 output[count[index]-1] = arr[i] count[index]-- }
for i := 0; i < n; i++ { arr[i] = output[i] } }
func radixSort(arr []int) { maxNum := arr[0] n := len(arr)
for i := 1; i < n; i++ { if arr[i] > maxNum { maxNum = arr[i] } }
exp := 1
for maxNum/exp > 0 { countingSort(arr, exp) exp *= 10 } }
func main() { arr := []int{170, 45, 75, 90, 802, 24, 2, 66} radixSort(arr) fmt.Println("排序后的数组:", arr) }
|
Java 基数排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| import java.util.Arrays;
public class RadixSort { public static void countingSort(int arr[], int exp) { int n = arr.length; int output[] = new int[n]; int count[] = new int[10];
for (int i = 0; i < n; i++) { int index = arr[i] / exp % 10; count[index]++; }
for (int i = 1; i < 10; i++) { count[i] += count[i - 1]; }
for (int i = n - 1; i >= 0; i--) { int index = arr[i] / exp % 10; output[count[index] - 1] = arr[i]; count[index]--; }
for (int i = 0; i < n; i++) { arr[i] = output[i]; } }
public static void radixSort(int arr[]) { int maxNum = Arrays.stream(arr).max().getAsInt(); int exp = 1;
while (maxNum / exp > 0) { countingSort(arr, exp); exp *= 10; } }
public static void main(String[] args) { int arr[] = {170, 45, 75, 90, 802, 24, 2, 66}; radixSort(arr); System.out.print("排序后的数组: "); System.out.println(Arrays.toString(arr)); } }
|
C 语言 基数排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include <stdio.h>
void countingSort(int arr[], int n, int exp) { int output[n]; int count[10] = {0};
for (int i = 0; i < n; i++) { count[(arr[i] / exp) % 10]++; }
for (int i = 1; i < 10; i++) { count[i] += count[i - 1]; }
for (int i = n - 1; i >= 0; i--) { output[count[(arr[i] / exp) % 10] - 1] = arr[i]; count[(arr[i] / exp) % 10]--; }
for (int i = 0; i < n; i++) { arr[i] = output[i]; } }
void radixSort(int arr[], int n) { int maxNum = arr[0];
for (int i = 1; i < n; i++) { if (arr[i] > maxNum) { maxNum = arr[i]; } }
int exp = 1;
while (maxNum / exp > 0) { countingSort(arr, n, exp); exp *= 10; } }
int main() { int arr[] = {170, 45, 75, 90, 802, 24, 2, 66}; int n = sizeof(arr) / sizeof(arr[0]); radixSort(arr, n); printf("排序后的数组: "); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; }
|
以上示例代码展示了不同编程语言中的基数排序算法实现。这些示例帮助你理解基数排序的工作原理,并提供了可供参考和使用的代码示例。基数排序是一种适用于整数排序的高效稳定的排序算法。