排序算法的c++实现——计数排序
任何比较排序算法的时间复杂度的上限为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++实现——计数排序的更多相关文章
- 排序算法<No.1> 【计数排序】
继上篇博文,今天我将先介绍一下什么是计数排序,将计数排序描述清楚后,再进行后续的桶排序方法解决这个问题. 通常情况下,一提到排序,大家第一反应就是比较,其实,今天我要说的这个计数排序,不是基于比较的排 ...
- 算法-java代码实现计数排序
计数排序 第10节 计数排序练习题 对于一个int数组,请编写一个计数排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3], ...
- Python实现八大排序算法(转载)+ 桶排序(原创)
插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...
- 排序算法<No.7>【希尔排序】
排序算法进入到第7篇,这个也还是比较基础的一种,希尔排序,该排序算法,是依据该算法的发明人donald shell的名字命名的.1959年,shell基于传统的直接插入排序算法,对其性能做了下提升,其 ...
- C语言排序算法之简单交换法排序,直接选择排序,冒泡排序
C语言排序算法之简单交换法排序,直接选择排序,冒泡排序,最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 简单交换法排序 /*简单交换法排序 根据序列中两个记录键值的比较结果来对换这两 ...
- Java排序算法(四)希尔排序2
Java排序算法(四)希尔排序2 希尔排序移步法:分组+直接插入排序组合 一.测试类SortTest import java.util.Arrays; public class SortTest { ...
- 基于visual Studio2013解决算法导论之012计数排序
题目 计数排序 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...
- 排序算法(9)--Distribution Sorting--分布排序[1]--Counting sort--计数器排序
1.基本思想 假设数序列中小于元素a的个数为n,则直接把a放到第n+1个位置上.当存在几个相同的元素时要做适当的调整,因为不能把所有的元素放到同一个位置上.计数排序假设输入的元素都是0到k之间的整数. ...
- 排序算法c语言描述---选择排序
排序算法系列学习,主要描述冒泡排序,选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等排序进行分析. 文章规划: 一.通过自己对排序算法本身的理解,对每个方法写个小测试程序. 具体思路分析 ...
随机推荐
- mysql Navicat通过代理链接数据库
1.做完host 账号 密码(数据库服务器)配置之后,选择ssh 2.配置代理服务器ip的登录的账号密码.(代理服务器必须可以连你的Navicat客户端和数据库服务器,不然怎么做代理.) 3.可以直接 ...
- 修改了celery任务老是执行失败,跟shell中调试的结果不同
因为没有重启celery,没有删除celerybeat-schedule,导致使用的task任务一直是原来缓存的,所以代码一直无法生效,也是日了狗了
- Codeforces Round 564 题解
很抱歉让标题把您骗进来了. 这是一场打得最失败的div1. 作为一个橙名一题都不会…… 旁边紫名的PB怒切3题,div2的也随便玩玩出了div1b/div2d…… 这名字颜色也太有水分了. 也就只会2 ...
- 基于Linux(中标麒麟)上QT的环境搭建
最近由于公司需要,需要在中标麒麟上进行QT的二次开发,但是网上的资料很少,就算是有也基本都是其他的版本的Linux上的搭建.中标麒麟本身的资料也很好,而且还只能试用60天. 下面就介绍下我对此环境的搭 ...
- vb.net 读取 excel
Dim myConn AsNew ADODB.Connection myConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient ' 用 ...
- jquery根据选择器进行页面赋值,封装赋值方法
可以进行文本框赋值,文本域赋值,下拉列表赋值,单选框赋值,多选框赋值, 传入对象,可以根据元素name进行比对赋值,不用每个进行单独赋值 <!DOCTYPE html> <html ...
- CnblogAndroid使用反馈 & PureMan6留言板
我们的话: 您可以在这篇博客下评论您使用CnblogAndroid时遇到的问题和您的意见与建议: 或是留言给PureMan6团队,我们会定期查看并进行回复. 同时,关于app的问题,您也可以在Cnbl ...
- 【Gamma】测试报告
测试方法及过程 在正式发布前,我们对后端代码.前后端接口.服务器以及前端的页面和功能做了多种测试,主要包括对后端代码的单元测试.针对接口的测试.压力测试以及功能测试. 后端代码单元测试 该部分测试主要 ...
- Eureka比Zookeeper好在哪里?
Eureka遵守AP,Zookeeper遵守CP RDBMS(oracle/mysql.sqlServer) ====> ACID, 关系型数据库遵循ACID原则: NoSQL(redis/mo ...
- Python 3.X 练习集100题 02
企业发放的奖金根据利润提成.利润(I):低于或等于10万元时,奖金可提10%:高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:20万到40万之间时,高 ...