经典算法之计数排序

简介:
一 引言
计数排序假设 n 个输入元素中的每一个都是介于 0-k 的整数,此处 k 为某个整数。当k等于O(n)时,计数排序的运行时间为Θ(n)。

二 基本思想
计数排序的基本思想就是对每一个输入元素x,确定小于x的元素个数。因此我们就可以直接把x放到最终输出数组中的相应位置上。
例如:
如果有17个元素小于x,则x就位于第18个输出的位置上。当然有几个元素相同时,这个方法就略微改进一下,因为不能将它们放在同一个位置上。

三 具体实现

假定输入数组为A[1..n],他们的值均位于0~k之间,输出排序之后的数组为B[1..n],以及临时存储数组C[0..k]。计数排序的伪代码如下:
上图显示出了计数排序的运行过程。
在第1~2行中的for循环初始化操作之后,在第3~4行检查输入的每一个元素。如果输入元素 的值为i,即增加C[i]的值。C[i]记录了值为i的元素个数。
于是,在第4行之后C[i]中存放了等于i的元素的个数。在第6~7行中,通过 数组C中记录计数和,可以确定对每一个i=0,1,2.....,k,有多少输入元素是小于等于i的。
最后,在第9~11行中的for循环部分,把每一个 元素A[j]放在输出数组B中与其相应的最终位置上。如果每一个元素都不相同,则当第一次执行第9行时,对每一个A[j],值C[A[j]]即 为A[j]在输出数组上的最终位置上,因为共有C[A[j]]个元素小于等于A[j]。
可是由于各个元素可能不一定是不同的,因此,每当将一个值A[j]放入数组B中时,都要减小C[A[j]]额值。这会使得下一个值等于A[j]的输入元素直接进入输出数组B中A[j]的前一个位置。

四 代码
/*********************************
*   日期:2014-04-26
*   作者:SJF0115
*   题目: 计数排序
**********************************/
#include <iostream>
#include <stdio.h>
using namespace std;


void COUNTINGSORT(int *A,int *B,int len,int k){
    if(A == NULL || k <= 0 || len <= 0){
        return;
    }
    int C[k+1],i;
    //初始化
    for(i = 0;i <= k;i++){
        C[i] = 0;
    }
    //统计值为A[i]的个数,C[i]是等于i的元素个数
    for(i = 0;i < len;i++){
        C[A[i]] ++;
    }
    //确定值A[i]在最终输出数组B中位置,C[i]是小于等于i的元素个数
    for(i = 1;i <= k;i++){
        C[i] += C[i-1];
    }
    //输出到数组B中
    for(i = len-1;i >= 0;i--){
        //index元素A[i]在数组B中的下标
        int index = C[A[i]];
        B[index] = A[i];
        //如果有相同值元素的情况
        C[A[i]] --;
    }
    //B下标从1开始
}

int main(){
    int A[8] = {2,5,3,0,2,3,0,3};
    int B[9];
    COUNTINGSORT(A,B,8,5);
    for(int i = 1;i <= 8;i++){
        printf("%d\n",B[i]);
    }
    return 0;
}



五 时间复杂度分析

时间复杂度是多少呢?
第1~2行for循环所花时间为Θ(k)。
第3~4行 for循环所花时间为Θ(n)。
第6~7行for循环所花时间为Θ(k)。
第9~11行 for循环所花时间为Θ(n)。
这样总的时间就是 Θ(k+n)。在实践中,档k = O(n)时,我们常采用计数排序,这时运行时间为 Θ(n)。

六 特点

1.  提前必须是已知待排序的关键字为整型且范围已知。

2.  时间复杂度为O(n+k),不是基于比较的排序算法,因此效率非常之高。

3.  稳定性好,这个是计数排序非常重要的特性,可以用在后面介绍的基数排序中。

4.  但需要一些辅助数组,如C[0..k],因此待排序的关键字范围0~k不宜过大。

目录
相关文章
|
算法 搜索推荐 Python
Python算法——计数排序
Python算法——计数排序
143 0
|
算法 搜索推荐
数据结构算法--6 希尔排序和计数排序
**希尔排序**是插入排序的改进版,通过分组插入来提高效率。它逐步减少元素间的间隔(增量序列),每次对每个间隔内的元素进行插入排序,最终增量为1时进行最后一次直接插入排序,实现整体接近有序到完全有序的过程。例如,对数组`5, 7, 4, 6, 3, 1, 2, 9, 8`,先以间隔`d=4`排序,然后`d=2`,最后`d=1`,完成排序。计数排序则适用于0到100的数值,通过统计每个数出现次数,创建对应计数数组,再根据计数重建有序数组,时间复杂度为`O(n)`。
|
搜索推荐 Java Go
深入了解计数排序算法
深入了解计数排序算法
155 4
|
算法 搜索推荐 大数据
【算法】排序——归并排序和计数排序
上两篇文章讲解了插入排序、选择排序以及交换排序,每种类型的排序大类下都有一到两种排序,今天给大家带来的是归并排序,和前面几种排序一样都属于比较排序中的一种,是通过比较数组中的元素来实现排序的,还给大家带来一种非比较排序计数排序,让我们开始今天的排序之吧!!!
|
存储 算法 搜索推荐
|
存储 算法 前端开发
前端算法之计数排序
前端算法之计数排序
82 1
|
搜索推荐
排序算法之八:计数排序
排序算法之八:计数排序
139 1
排序算法之八:计数排序
|
搜索推荐 算法
【C/排序算法】:归并排序和计数排序
【C/排序算法】:归并排序和计数排序
103 0
|
存储 搜索推荐 算法
【数据结构】八大排序之计数排序算法
【数据结构】八大排序之计数排序算法
138 4
|
搜索推荐 C语言
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
107 0

热门文章

最新文章

下一篇
日志分析软件