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

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

基数排序:是一种多关键字排序算法,基数排序的实现由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、付费专栏及课程。

余额充值