计数排序算法

计数排序(Counting sort)是一种稳定的线性时间排序算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。

本文地址:http://www.cnblogs.com/archimedes/p/counting-sort-algorithm.html,转载请注明源地址。

计数排序的特征

当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。

由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。例如:计数排序是用来排序0到100之间的数字的最好的算法,但是它不适合按字母顺序排序人名。但是,计数排序可以用在基数排序中的算法来排序数据范围很大的数组。

通俗地理解,例如有10个年龄不同的人,统计出有8个人的年龄比A小,那A的年龄就排在第9位,用这个方法可以得到其他每个人的位置,也就排好了序。当然,年龄有重复时需要特殊处理(保证稳定性),这就是为什么最后要反向填充目标数组,以及将每个数字的统计减去1的原因。

算法的步骤如下:

  1. 找出待排序的数组中最大和最小的元素
  2. 统计数组中每个值为i的元素出现的次数,存入数组C的第i
  3. 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
  4. 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

对于数据2 5 3 0 2 3 0 3程序执行的过程如下图所示:

算法实现

C代码如下:

// Completed on 2014.10.10 20:37
// Language: C99
//
// 版权所有(C)codingwu   (mail: [email protected])
// 博客地址:http://www.cnblogs.com/archimedes/
#include<stdio.h>
#include<stdlib.h>
int* countingSort(int *a, int n, int k)
{
    int c[k + 1], i, value, pos;
    int *b = (int *)malloc(n * sizeof(int));
    for(i = 0; i <= k; i++)  //初始化
        c[i] = 0;
    for(i = 0; i < n; i++)
        c[a[i]]++;
    for(i = 1; i <= k; i++)
        c[i] = c[i] + c[i - 1];
    for(i = n - 1; i >= 0; i--) {
        value = a[i];
        pos = c[value];
        b[pos - 1] = value;
        c[value]--;
    }
    return b;
}
int maxArr(int *a, int n)  //返回数组中最大的元素
{
    int i, max;
    max = a[0];
    i = 1;
    int *p;
    p = a + 1;
    while(i++ < n) {
        if(max < *p)
            max = *p;
        p++;
    }
    return max;
}
int main()
{
    int a[] = {2, 5, 3, 0, 2, 3, 0, 3};
    int N, max;
    N = sizeof(a) / sizeof(a[0]);
    max = maxArr(a, N);
    int *p = countingSort(a, N, max);
    for(int k = 0; k < N; k++)
        printf("%d ", p[k]);
    printf("\n");
    free(p);
    return 0;
}

对代码有疑惑的可以参考《C语言指针传递详解

时间: 2024-10-12 17:03:16

计数排序算法的相关文章

一文弄懂计数排序算法!

这是小川的第385次更新,第413篇原创 01 计数排序算法概念 计数排序不是一个比较排序算法,该算法于1954年由 Harold H. Seward提出,通过计数将时间复杂度降到了O(N). 02 基础版算法步骤 第一步:找出原数组中元素值最大的,记为max. 第二步:创建一个新数组count,其长度是max加1,其元素默认值都为0. 第三步:遍历原数组中的元素,以原数组中的元素作为count数组的索引,以原数组中的元素出现次数作为count数组的元素值. 第四步:创建结果数组result,起

桶排序,计数排序算法

计数排序: 桶排序:www.roading.org/algorithm/introductiontoalgorithm 算法模型: 1,桶排序假设待排的一组数统一分布在一个范围[m....n],将这一范围划分为几个子范围,也就是桶bucket. 例如,如何将0---999范围的数,划分到10个桶中?范围中数的个数用K表示,那么K/10=1000/10=100,就是每个桶装100个元素,即[0..99]装到第一个桶中,[100..199]装到第二个桶中,...以此类推. 怎么判断一个数组该放到哪个

计数排序算法——时间复杂度O(n+k)

计数排序 计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出.它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法. 算法思想 计数排序对输入的数据有附加的限制条件: 1.输入的线性表的元素属于有限偏序集S: 2.设输入的线性表的长度为n,|S|=k(表示集合S中元素的总数目为k),则k=O(n). 在这两个条件下,计数排序的复杂性为O(n). 计数排序的基本思想是对于给定的输入序列中的每一个元

计数排序 - 算法数据结构面试分享(五)

数组排序问题 - 计数排序 昨天我们留了一道题目"给你一个整型数组,里面出现的数在[0-100] 之间,能用最优化的方法帮我排序吗". 1. 确保我们理解了问题,并且尝试一个例子,确认理解无误. 这是一道排序算法题,我们学过很多排序的算法.不一样的是,它给定一个额外的条件,数组里的每个数字都在1-100之间.如果我们采取传统的排序算法,这个条件我们好像用不上.大家在面试的时候如果发现有条件没有用上,基本上我们给出的算法可能不是最优的,或者我们没有解决它最原始的需求.举个例子{50, 4

PHP 计数排序算法

计数排序只适用于整数在小范围内排序 $arr = [95,94,91,98,99,90,99,93,91,92];function countSort($arr){ $max = $arr[0]; $min = $arr[0]; for($i=0;$i<count($arr);$i++){ if($arr[$i]>$max){ $max = $arr[$i]; } if($arr[$i] < $min){ $min = $arr[$i]; } } try{ $frequency = ne

算法-java代码实现计数排序

计数排序 第10节 计数排序练习题 对于一个int数组,请编写一个计数排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] Java (javac 1.7) 代码自动补全 1 import java.util.*; 2 3 public class CountingSort { 4 public int[] countingSort(int[] A, int n) { 5 countingSo

算法——计数排序与快速排序

计数排序是一种算法复杂度 O(n) 的排序方法,适合于小范围集合的排序.比如100万学生参加高考,我们想对这100万学生的数学成绩(假设分数为0到100)做个排序.我们如何设计一个 最高效的排序算法.本文不光给出计数排序算法的传统写法,还将一步步深入讨论算法的优化,直到时间复杂度和空间复杂度最优. 先看看计数排序的定义 Counting sort (sometimes referred to as ultra sort or math sort[1]) is a sorting algorith

算法导论之六:线性时间排序之 决策树&amp;计数排序

本系列前五篇都是讲述的比较排序算法,从本文开始,将进入线性时间排序.什么是比较排序,简单的说,就是排序的过程依赖于数组中数据大小的比较,从而来确定数据在排好序输出时的位置. 比较排序法比较直观,但是也有它的不足,我们容易证明任何比较排序法,在最坏的情况下的时间复杂度的下限都是 nlgn.要证明这个问题,我们首先要搞清楚一个模型:决策树模型. 一.决策树模型 什么是决策树?决策树从形态上来讲,是一颗完全二叉树,它除叶子节点之外,其他层的节点都是满的.它的每一个叶子节点表示对输入数据组合的一种排序可

线性排序算法---- 计数排序, 基数排序, 桶排序

排序算法里,除了比较排序算法(堆排序,归并排序,快速排序),还有一类经典的排序算法-------线性时间排序算法.听名字就让人兴奋! 线性时间排序,顾名思义,算法复杂度为线性时间O(n) , 非常快,比快速排序还要快的存在,简直逆天.下面我们来仔细看看三种逆天的线性排序算法, 计数排序,基数排序和桶排序. 1计数排序  counting Sort 计数排序 假设 n个 输入元素中的每一个都是在 0 到 k 区间内的一个整数,当 k= O(N) 时,排序运行的时间为 O(N). 计数排序的基本思想