排序算法的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. 计数排序还是原址排序,它需要借助额外的内存空间。

代码如下:

  1   /***********************************************************************
  2   *   Copyright (C) 2019  Yinheyi. <[email protected]>
  3   *
  4   * This program is free software; you can redistribute it and/or modify it under the terms
  5   * of the GNU General Public License as published by the Free Software Foundation; either
  6   * version 2 of the License, or (at your option) any later version.
  7
  8   *   Brief:
  9   *   Author: yinheyi
 10   *   Email: [email protected]
 11   *   Version: 1.0
 12   *   Created Time: 2019年05月11日 星期六 10时19分07秒
 13   *   Modifed Time: 2019年05月11日 星期六 14时00分09秒
 14   *   Blog: http://www.cnblogs.com/yinheyi
 15   *   Github: https://github.com/yinheyi
 16   *
 17   ***********************************************************************/
 18   #include<string.h>
 19   #include<iostream>
 20
 21   // 任何比较排序算法的时间复杂度的上限为O(NlogN), 不存在比o(nlgN)更少的比较排序算法。
 22   // 如果想要在时间复杂度上超过O(NlogN)的时间复杂度,肯定需要加入其它条件。计数排序就加入
 23   // 了限制条件,从而使时间复杂度为O(N).
 24   //
 25   // 计数排序的核心思想(来自算法导论):
 26   // 计数排序要求待排序的n个元素的大小在[0, k]之间,并且k与n在一个数量级上,即k=O(n).
 27   // 对于每一个输入元素x, 确定小于等于x的个数为i。利用这一信息,就可以把元素x放到输出数组
 28   // 的正确位置,即把元素x放到输出数组下标为i-1的位置。
 29   //
 30   // 重要说明:
 31   // 1. 计数排序要求待排序的n个元素的大小在[0, k]之间,并且k与n在一个数量级上,即k=O(n).
 32   // 此时使用计数排序可以把时间复杂度降到O(n)上。
 33   // 2. 计数排序不是基于比较的排序算法,它基于计数策略。
 34   // 3. 写计数排序算法时,应该把它写成稳定排序的。
 35   // 4. 计数排序还是原址排序,它需要借助额外的内存空间。
 36   //
 37   // 计数排序代码如下:
 38   // 参数说明:array表示数组指针,nLength_表示数组的最大长度,nMaxNumber_表示数组元素中的最大>  值;
 39   void CountingSort(int array[], int nLength_, int nMaxNumber_)
 40   {
 41       // 参数的合法化检测
 42       if (nullptr == array || nLength_ <= 1 || nMaxNumber_ <= 0)
 43           return;
 44
 45       // 统计待排序数组中每一个元素的个数
 46       // 注意:此处new出来的数组的大小为nMaxNumber_ + 1, 用于统计[0, nMaxNumber_]范围内的元素
 47       int* ArrayCount = new int[nMaxNumber_ + 1]{0};
 48       for (int i = 0; i < nLength_; ++i)
 49       {
 50           ++ArrayCount[array[i]];
 51       }
 52
 53       // 此处计算待排序数组中小于等于第i个元素的个数.
 54       // 备注:如果要进行大到小的排序,就计算大于等于第i个元素的个数, 也就从后向前进行累加;
 55       for (int i = 1; i < nMaxNumber_ + 1; ++i)
 56       {
 57           ArrayCount[i] += ArrayCount[i-1];
 58       }
 59
 60       // 把待排序的数组放到输出数组中, 为了保持排序的稳定性,从后向前添加元素
 61       int* ArrayResult = new int[nLength_];
 62       for (int i = nLength_ - 1; i >=0; --i)
 63       {
 64           int _nIndex = ArrayCount[array[i]] - 1; // 元素array[i]在输出数组中的下标
 65           ArrayResult[_nIndex] = array[i];
 66
 67           // 因为可能有重复的元素,所以要减1,为下一个重复的元素计算正确的下标;
 68           --ArrayCount[array[i]];
 69       }
 70
 71       // 交换数据并释放内存空间
 72       memcpy(array, ArrayResult, sizeof(int) * nLength_);
 73       delete [] ArrayCount;
 74       ArrayCount = nullptr;
 75       delete [] ArrayResult;
 76       ArrayResult = nullptr;
 77   }
 78
 79   // 测试代码
 80   /***************    main.c     *********************/
 81   static void PrintArray(int array[], int nLength_);
 82   int main(int argc, char* argv[])
 83   {
 84       int test[10] = {12, 12, 4, 0, 8, 5, 2, 3, 9, 8};
 85       std::cout << "排序前:" << std::endl;
 86       PrintArray(test, 10);
 87       CountingSort(test, 10, 12);
 88       std::cout << "排序后:" << std::endl;
 89       PrintArray(test, 10);
 90
 91       return 0;
 92   }
 93
 94   // 打印数组函数
 95   static void PrintArray(int array[], int nLength_)
 96   {
 97       if (nullptr == array || nLength_ <= 0)
 98           return;
 99
100       for (int i = 0; i < nLength_; ++i)
101       {
102           std::cout << array[i] << " ";
103       }
104
105       std::cout << std::endl;
106   }

原文地址:https://www.cnblogs.com/yinheyi/p/10849708.html

时间: 2024-10-13 08:58:09

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

算法-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

【数据结构】——排序算法——3.1、选择排序

      [数据结构]--排序算法--3.1.选择排序 一.先上维基的图: 分类 排序算法 数据结构 数组 最差时间复杂度 О(n2) 最优时间复杂度 О(n2) 平均时间复杂度 О(n2) 最差空间复杂度 О(n) total, O(1)auxiliary 二.描述: 选择算法算是最直观的一个了.每次在队列里抽取一个极大(或极小)值进行排列.每次都需要遍历未被抽取的元素队列. 三.Java程序: static void selection_sort(int[] unsorted) { for

排序算法之一--冒泡排序,选择排序,插入排序

一.排序算法定义 1.排序算法定义 排序算法是一种能将一串数据依照特定顺序进行排列的一种算法 2.六种排序算法理解方式 想象小时候老师给我们按照身高进行排队时用到的方法,脑子里面要浮现老师排身高的场面   以从矮到高进行排序为例 3.稳定性的定义 一个排序算法是稳定的,当有两个相等键值的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前. 二.三种基本排序算法 1.冒泡排序:"移" 把最高的移到最右边 第一次循环,找到最高的那个人放到最右边       方法

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

C语言排序算法之简单交换法排序,直接选择排序,冒泡排序,最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 简单交换法排序 1 /*简单交换法排序 2 根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置 3 交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动 4 不稳定 5 */ 6 #include<windows.h> 7 #include<stdio.h> 8 void main(){ 9 int i,j,arr[10

算法总结——三大排序(快排,计数排序,归并)

快排: 适用条件:方便...只要数字不是很多 复杂度:O(nlogn)  每一层n复杂度,共logn层 原理:利用一个随机数与最后面一个数交换,那么这个随机数就到了最后一位,然后循环,如果前面的数大于最后一个数,那么把这个数放到前面去,经过一次排序之后,前面的数都是大于最后一个的,然后对1到k和k+1到n进行排序,一层一层地下去 模板: #include<cstdio> #include<algorithm> #include<time.h> using namespa

[一周一算法]算法导论学习之计数排序

计数排序是一种线性时间的排序,同时也是一种非比较排序 代码如下: 1 void CountingSort(int *data, int k, int num) // A ~ data[], B ~ aimArray[], C ~ tempArray[] 2 { 3 int *aimArray = new int[num]; 4 int *tempArray = new int[k + 1]; 5 for (int i = 0; i <= k; i++) 6 tempArray[i] = 0; 7

【数据结构】非比较排序的算法实现(包括计数排序、计数排序)

计数排序: #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; #include<assert.h> #include<vector> void Print(vector<int>  a) {     for (int i = 0; i < a.size(); i++)     {         cout << a[i] << &q

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

1.基本思想 假设数序列中小于元素a的个数为n,则直接把a放到第n+1个位置上.当存在几个相同的元素时要做适当的调整,因为不能把所有的元素放到同一个位置上.计数排序假设输入的元素都是0到k之间的整数. 2.实现原理 为一组数在排序之前先统计这组数中其他数小于这个数的个数,则可以确定这个数的位置.例如要排序的数为 7 4 2 1 5 3 1 5:则比7小的有7个数,所有7应该在排序好的数列的第八位,同理3在第四位,对于重复的数字,1在1位和2位(暂且认为第一个1比第二个1小),5和1一样位于6位和

常见排序算法导读(3)[简单选择排序]

这一节将介绍简单选择排序(Simple Selection Sort). 在介绍简单排序算法之前,先给出排序的确切定义,并简单介绍一下排序算法的稳定性. 排序的确切定义 假设含有n个对象的序列为{R[0], R[1], ..., R[n-1]}, 其对应的关键字(key)序列为{K[0], K[1], ..., K[n-1]}. 所谓排序, 就是确定0, 1, ..., n-1的一种排列p[0], p[1], ..., p[n-1], 使各个关键字满足如下的非递减(升序)或非递增(降序)关系: