8.5内部排序法---分配类排序(基数排序)

本文深入探讨了基数排序算法,一种基于分配类的排序方法,不同于传统的比较排序算法。它通过3个核心步骤:初始化静态链表、分配和收集,实现了高效排序。重点介绍了基数排序的时间复杂度及其实现细节,并通过示例代码展示了其在内部排序中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分配类排序与前面介绍的排序方法 ,它不是比较元素的大小,然后交换元素,而分配类排序算法主要包括分配和收集两个部分。基数排序是常用的分配类排序算法

基数排序:是一种多关键字排序算法,基数排序的实现由3个部分组成:

初始化静态链表、分配和收集。

时间复杂度为   Ω(n·log2(n)) = Ω(n·log n) 

下面是其操作:

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/***********************************************************/
// 程序名称:radixSort.cpp
// 程序目的:内部排序法---分配类排序(基数排序)
// 程序来源:互联网
// 日期:2013-9-10 20:19:25 JohnnyHu修改
/***********************************************************/

#include <stdio.h>
#include <stdlib.h>

#define     MAX     5   
#define     WIDTH   4       // 被排序元素的最大位数,4则意味着只能排序< 10000 的数
#define     MAXK    10      // 位数划分基于的基数,10表示为10进制划分
typedef int ElementType;

void radixSort(int a[], int n);
void innerCountingSort(int a[], int n, int d);
int getDValue(int value, int d);
void PrintSort(ElementType a[], int n);

int main(void)
{
    int data[MAX] = {891245833};

    printf("排序前: ");
    PrintSort(data, MAX);

    radixSort(data, MAX);

    printf("排序后: ");
    PrintSort(data, MAX);

    return 0;
}

/************************************************************************/
// 基数排序
/************************************************************************/

void radixSort(int a[], int n)
{
    int i;
    for (i = 0; i < WIDTH; i++)     // WIDTH趟
    {
        innerCountingSort(a, n, i);
    }
}


/************************************************************************/
// 根据第d位数对数组进行排序
/************************************************************************/

void innerCountingSort(int a[], int n, int d)
{
    // ip用来存储待排序数组的元素的某一位的数值  
    int* ip = (int*)malloc(n * sizeof(int));
    int* bp = (int*)malloc(n * sizeof(int));

    int  k[MAXK] = {0}; // 数组K用来统计某一个元素的个数,该元素为要排序的元素的各位上数值大小
    for (int i = 0; i < n; i++) 
    {
        ip[i] = getDValue(a[i], d); // a[i]第d位值赋给ip[i](ip[i]取值范围0...9)
        k[ip[i]]++;                 // 总数据中第d位的关键字个数
    }

    // 统计小于等于j的元素个数(j=0...9)  
    for (int j = 1; j < MAXK; j++) 
    {
        k[j] = k[j] + k[j-1];
    }

    // 按照第d位的大小,将数组元素放置到正确的位置  
    for (int i = n - 1; i >= 0; i--) 
    {
        bp[k[ip[i]] - 1] = a[i];
        k[ip[i]]--;
    }

    // 将按某一位排过序后的数组复制给原数组  
    for (int i = 0; i < n; i++)
    {
        a[i] = bp[i];
    }

    free(ip);
    free(bp);
}

/************************************************************************/
// 获取一个数第d位数的值,位数索引从0开始
/************************************************************************/

int getDValue(int value, int d)
{
    for ( ; d > 0 && value > 0; d--) 
    {
        value = value / MAXK;
    }
    return value % MAXK;
}

/************************************************************************/
// 打印排序表
/************************************************************************/

void PrintSort(ElementType a[], int n)
{
    for (int i = 0; i < n; i++)
        printf("[%d]\t", a[i]);
    printf("\n");

    return;
}

输出结果:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值