任何比较排序算法的时间复杂度的上限为O(NlogN), 不存在比o(nlgN)更少的比较排序算法。如果想要在时间复杂度上超过O(NlogN)的时间复杂度,肯定需要加入其它条件。计数排序就加入了限制条件,从而使时间复杂度为O(N).

计数排序的核心思想(来自算法导论):计数排序要求待排序的n个元素的大小在[0, k]之间,并且k与n在一个数量级上,即k=O(n).对于每一个输入元素x, 确定小于等于x的个数为i。利用这一信息,就可以把元素x放到输出数组的正确位置,即把元素x放到输出数组下标为i-1的位置。
 
   重要说明:
   1. 计数排序要求待排序的n个元素的大小在[0, k]之间,并且k与n在一个数量级上,即k=O(n).
   此时使用计数排序可以把时间复杂度降到O(n)上。
   2. 计数排序不是基于比较的排序算法,它基于计数策略。
   3. 写计数排序算法时,应该把它写成稳定排序的。
   4. 计数排序还是原址排序,它需要借助额外的内存空间。

代码如下:

   /***********************************************************************
* Copyright (C) 2019 Yinheyi. <chinayinheyi@163.com>
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version. * Brief:
* Author: yinheyi
* Email: chinayinheyi@163.com
* Version: 1.0
* Created Time: 2019年05月11日 星期六 10时19分07秒
* Modifed Time: 2019年05月11日 星期六 14时00分09秒
* Blog: http://www.cnblogs.com/yinheyi
* Github: https://github.com/yinheyi
*
***********************************************************************/
#include<string.h>
#include<iostream> // 任何比较排序算法的时间复杂度的上限为O(NlogN), 不存在比o(nlgN)更少的比较排序算法。
// 如果想要在时间复杂度上超过O(NlogN)的时间复杂度,肯定需要加入其它条件。计数排序就加入
// 了限制条件,从而使时间复杂度为O(N).
//
// 计数排序的核心思想(来自算法导论):
// 计数排序要求待排序的n个元素的大小在[0, k]之间,并且k与n在一个数量级上,即k=O(n).
// 对于每一个输入元素x, 确定小于等于x的个数为i。利用这一信息,就可以把元素x放到输出数组
// 的正确位置,即把元素x放到输出数组下标为i-1的位置。
//
// 重要说明:
// 1. 计数排序要求待排序的n个元素的大小在[0, k]之间,并且k与n在一个数量级上,即k=O(n).
// 此时使用计数排序可以把时间复杂度降到O(n)上。
// 2. 计数排序不是基于比较的排序算法,它基于计数策略。
// 3. 写计数排序算法时,应该把它写成稳定排序的。
// 4. 计数排序还是原址排序,它需要借助额外的内存空间。
//
// 计数排序代码如下:
// 参数说明:array表示数组指针,nLength_表示数组的最大长度,nMaxNumber_表示数组元素中的最大> 值;
void CountingSort(int array[], int nLength_, int nMaxNumber_)
{
// 参数的合法化检测
if (nullptr == array || nLength_ <= || nMaxNumber_ <= )
return; // 统计待排序数组中每一个元素的个数
// 注意:此处new出来的数组的大小为nMaxNumber_ + 1, 用于统计[0, nMaxNumber_]范围内的元素
int* ArrayCount = new int[nMaxNumber_ + ]{};
for (int i = ; i < nLength_; ++i)
{
++ArrayCount[array[i]];
} // 此处计算待排序数组中小于等于第i个元素的个数.
// 备注:如果要进行大到小的排序,就计算大于等于第i个元素的个数, 也就从后向前进行累加;
for (int i = ; i < nMaxNumber_ + ; ++i)
{
ArrayCount[i] += ArrayCount[i-];
} // 把待排序的数组放到输出数组中, 为了保持排序的稳定性,从后向前添加元素
int* ArrayResult = new int[nLength_];
for (int i = nLength_ - ; i >=; --i)
{
int _nIndex = ArrayCount[array[i]] - ; // 元素array[i]在输出数组中的下标
ArrayResult[_nIndex] = array[i]; // 因为可能有重复的元素,所以要减1,为下一个重复的元素计算正确的下标;
--ArrayCount[array[i]];
} // 交换数据并释放内存空间
memcpy(array, ArrayResult, sizeof(int) * nLength_);
delete [] ArrayCount;
ArrayCount = nullptr;
delete [] ArrayResult;
ArrayResult = nullptr;
} // 测试代码
/*************** main.c *********************/
static void PrintArray(int array[], int nLength_);
int main(int argc, char* argv[])
{
int test[] = {, , , , , , , , , };
std::cout << "排序前:" << std::endl;
PrintArray(test, );
CountingSort(test, , );
std::cout << "排序后:" << std::endl;
PrintArray(test, ); return ;
} // 打印数组函数
static void PrintArray(int array[], int nLength_)
{
if (nullptr == array || nLength_ <= )
return; for (int i = ; i < nLength_; ++i)
{
std::cout << array[i] << " ";
} std::cout << std::endl;
}

排序算法的c++实现——计数排序的更多相关文章

  1. 排序算法<No.1> 【计数排序】

    继上篇博文,今天我将先介绍一下什么是计数排序,将计数排序描述清楚后,再进行后续的桶排序方法解决这个问题. 通常情况下,一提到排序,大家第一反应就是比较,其实,今天我要说的这个计数排序,不是基于比较的排 ...

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

    计数排序   第10节 计数排序练习题 对于一个int数组,请编写一个计数排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3], ...

  3. Python实现八大排序算法(转载)+ 桶排序(原创)

    插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...

  4. 排序算法<No.7>【希尔排序】

    排序算法进入到第7篇,这个也还是比较基础的一种,希尔排序,该排序算法,是依据该算法的发明人donald shell的名字命名的.1959年,shell基于传统的直接插入排序算法,对其性能做了下提升,其 ...

  5. C语言排序算法之简单交换法排序,直接选择排序,冒泡排序

    C语言排序算法之简单交换法排序,直接选择排序,冒泡排序,最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 简单交换法排序 /*简单交换法排序 根据序列中两个记录键值的比较结果来对换这两 ...

  6. Java排序算法(四)希尔排序2

    Java排序算法(四)希尔排序2 希尔排序移步法:分组+直接插入排序组合 一.测试类SortTest import java.util.Arrays; public class SortTest { ...

  7. 基于visual Studio2013解决算法导论之012计数排序

     题目 计数排序 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...

  8. 排序算法(9)--Distribution Sorting--分布排序[1]--Counting sort--计数器排序

    1.基本思想 假设数序列中小于元素a的个数为n,则直接把a放到第n+1个位置上.当存在几个相同的元素时要做适当的调整,因为不能把所有的元素放到同一个位置上.计数排序假设输入的元素都是0到k之间的整数. ...

  9. 排序算法c语言描述---选择排序

    排序算法系列学习,主要描述冒泡排序,选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等排序进行分析. 文章规划: 一.通过自己对排序算法本身的理解,对每个方法写个小测试程序. 具体思路分析 ...

随机推荐

  1. RabbitMQ消息幂等性问题

    文章目录 1. 什么是幂等性?1.1 消息队列的幂等性1.2 模拟重试机制1.2.1 生产者代码1.2.2 消费者代码1.2.3 消费者 application.yml 配置2. 如何保证消息幂等性, ...

  2. v2.3.0

    v2.3.1 大版本2,小版本3,fixbug 1

  3. Layui 关闭当前标签页

    parent.layui.admin.events.closeThisTabs();

  4. 洛谷P1531 I Hate It题解

    题目背景 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 题目描述 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的 ...

  5. 洛谷 P2253 好一个一中腰鼓! 题解

    P2253 好一个一中腰鼓! 题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:"忽一人 ...

  6. 09-排序2 Insert or Merge (25 分)

    According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...

  7. Spring Boot 知识笔记(配置文件)

    Spring boot 提供了两种常用的配置文件,properties和yml文件. 1.yml yml是YAML(YAML Ain't Markup Language)语言的文件,以数据为中心,比j ...

  8. Apache tomcat高可用web集群搭建过程配置记录

    说明,本文仅作为个人搭建配置保存,问题处理没有一一列出,过程也未见详尽,有问题的朋友可以直接留言给我,会一一回复,谢谢. 小目标: 支持故障转移(或主备,扩展性不佳),保证故障转移后,对前端用户透明, ...

  9. 通过inspect在电脑的Chrome上查看手机上的H5

    首先打开手机的开发者模式,(在连续点击7次版本号,系统会提示已经打开开发者模式) 然后打开一个手机浏览器. 然后在电脑上打开chrome://inspect/#devices.这是就会出现手机上浏览器 ...

  10. Oracle--存储过程中之循环语句

    一般循环语句有两种: 1)使用for循环实现 declare  cursor cur is    select * from tablename;   aw_row  tablename%rowtyp ...