//counting sort 计数排序
//参考算法导论8.2节
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
using namespace std;
const int k=5;
const int n=7;
int a[n]={5, 5, 1, 2 , 5, 4, 1};
int b[n];
int c[k+1]; int main()
{
int maxn=0;
memset(c, 0, sizeof c);
for(int i=0;i<n;i++)
{
c[a[i]]++;
maxn=max(maxn, a[i]);
}
assert(maxn<=k); //统计<=i的个数, c[i]就是最终i要放置的位置
for(int i=1;i<=maxn;i++)
{
c[i]+=c[i-1];
}
for(int i=0;i<=maxn;i++)
printf("%d ", c[i]);
printf("\n"); for(int i=n-1;i>=0;i--)
{
b[c[a[i]] - 1]=a[i];//从0开始
--c[a[i]];
} for(int i=0;i<n;i++)
printf("%d ", b[i]);
printf("\n");
return 0;
}

计数排序的总运行时间为θ(k + n),当k = O(n)时,运行时间为Θ(n)

优于比较排序的下界Ω(nlgn),因为在计数排序的过程中没有出现输入元素之间的比较,而是用了输入元素的实际值来确定它们在数组的位置。

额外插入排序算法的稳定。

排序算法的稳定的定义为:具有相同值的元素在输出数组中的相对次序与它们在输入数组中的次序相同。可参考维基

对于简单数据的排序,稳定性好像没什么作用,但是对于复杂数据(不只一项属性)的排序,稳定性很重要。

计数排序是稳定的排序,因此计数排序被用作基数排序算法的子过程。

 

练习8.2-2

在counting_sort过程中,假设将for(j = length; j >= 1; j--) 改为for(j = 1; j <= length; j++)。证明该算法仍能正常地工作,修改后的算法是稳定的吗?

计数排序算法不依赖数组A的顺序,所以仍能正常运行,而且结果正确。

但是修改后的算法不稳定。因为没修改前,在数组A里靠后的元素,在数组B也靠后(针对与元素值相同),如果修改后,结果会相反。违反了具有相同值的元素在输出数组中的相对次序与它们在输入数组中的次序相同,即稳定性。

 

练习8.2-4

给出一个算法,使之对于给定介于0和k之间的n个整数进行预处理,并能在O(1)时间内,回答出输入的整数中有多少个落在区间[a..b]内。你给出的算法的预处理时间应为Θ(n + k)。

用一个数组C,记录小于或等于其每个下标的值的元素个数。C[b] - C[a-1]为落在区间内的元素个数

Compute theCarray as is done in counting sort. The number of integers in the

range [a..b]isC[b]−C[a−1], where we interpretC[−1] as 0.

counting sort 计数排序的更多相关文章

  1. Uva-------(11462) Age Sort(计数排序)

    B Age Sort Input: Standard Input Output: Standard Output   You are given the ages (in years) of all ...

  2. 《算法导论》——计数排序Counting Sort

    今天贴出的算法是计数排序Counting Sort.在经过一番挣扎之前,我很纠结,今天这个算法在一些scenarios,并不是最优的算法.最坏情况和最好情况下,时间复杂度差距很大. 代码Countin ...

  3. 排序算法六:计数排序(Counting sort)

    前面介绍的几种排序算法,都是基于不同位置的元素比较,算法平均时间复杂度理论最好值是θ(nlgn). 今天介绍一种新的排序算法,计数排序(Counting sort),计数排序是一个非基于比较的线性时间 ...

  4. 【算法】计数排序(Counting Sort)(八)

    计数排序(Counting Sort) 计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中. 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范 ...

  5. 【算法导论】【排序】—— 计数排序(counting sort)

    计数排序的特点: 需要额外的数组以存储: 中间过程数据(记为数组 C),数组 C 的下标是待排序序列的元素值,下标对应的值为出现的次数: 排序后的序列(记为 B),计数排序仅获取原始待排序序列的值,对 ...

  6. 计数排序/Counting Sort

    计数排序的算法思想: 对于每一个元素x,只要确定了元素x有多少个比它小的元素,那么就可以知道其最终的位置. 记输入数组为A[n],存放最后排序输出的数组为B[n],提供临时存储空间的中间数组记为C[k ...

  7. 计数排序Counting sort

    注意与基数排序区分,这是两个不同的排序 计数排序的过程类似小学选班干部的过程,如某某人10票,作者9票,那某某人是班长,作者是副班长 大体分两部分,第一部分是拉选票和投票,第二部分是根据你的票数入桶 ...

  8. 数据结构与算法-排序(八)计数排序(Counting Sort)

    摘要 计数排序本质就是统计不同元素出现的次数,然后将元素依次从小到大放置,每个元素看统计的次数,就紧挨着放置几个同样的元素. 看似简单的处理,在算法中,会依据统计的元素次数推算出每个元素的索引位置,这 ...

  9. 计数排序与桶排序(bucket sort)

    Bucket Sort is a sorting method that subdivides the given data into various buckets depending on cer ...

随机推荐

  1. 如何在MySql中记录SQL日志

    SQL server有一个sql profiler可以实时跟踪服务器执行的SQL语句,这在很多时候调试错误非常有用.例如:别人写的复杂代码.生产系统.无调试环境.无原代码... ...   查了一下资 ...

  2. 企业服务总线Enterprise service bus介绍

    企业服务总线(Enterprise service bus). 以往企业已经实现了很多服务, 构成了面向服务的架构,也就是我们常说的SOA. 服务的参与双方都必须建立1对1 的联系,让我们回顾一下SO ...

  3. Nginx gzip配置详解

    gzip决定是否开启gzip模块param:on|offexample:gzip on; gzip_buffers 设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间param1:intp ...

  4. 【Android】创建、读取XML文件

    创建: package webdomain; import java.io.File; import java.io.FileNotFoundException; import java.io.Fil ...

  5. 设计模式 命令-Command

    命令-Command 当要向不同类的对象发出相同的请求时,可以将接收者和他的动作封装进一个命令对象.这样调用者只和命令产生依赖.而不会和众多的接收者发生依赖. Head First例子 要设计一款遥控 ...

  6. Window.onLoad 和 DOMContentLoaded事件的先后顺序

    相信写js的,都知道window.onload吧,但是并不是每个人都知道DOMContentLoaded,其实即使你不知道,很有可能你也经常使用了这个东西. 一般情况下,DOMContentLoade ...

  7. RPC基础篇

    RPC概念 RPC(Remote Procedure Call Protocol)——远程过程调用协议, 是一种进程间通信方式.它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数 ...

  8. LeetCode(7) - Reverse Integer

    题目的要求就是要反转一个Integer,例如输入123,则输出321,这一题比较tricky的地方就是它有可能越界,就是说1234567899,反过来是9987654321是一个越界的Integer, ...

  9. android学习笔记---发送状态栏通知

    发送消息的代码如下: //获取通知管理器 NotificationManager mNotificationManager = (NotificationManager) getSystemServi ...

  10. C# rmi例子

    接口定义 实体定义,注意需要序列化 using System; namespace Interface { [Serializable] public class DataEntity { publi ...