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

原创 2016年05月30日 17:19:34

对于比较排序,大家如果感兴趣,可以查看我的博客:http://10740184.blog.51cto.com/10730184/1774508


计数排序


思路:

我们假设升序排序
排序序列为2000,2001,3000,4000
遍历序列,取出最小值min,最大值max,开辟一个空间为max—min的空间大小的数组,遍历数组a将排序序列a中的每个元素出现的次数放在数组count的每个a[i]-min处。就是说,2000出现一次了,把次数1放在2000-2000位置处,2001出现的次数放在2001-2000位置上,3000出现的次数放在3000-2000位置上,4000出现的次数放在4000-2000位置上,5000出现的次数放在5000-2000位置上。后面遇到相同元素了,那将该位置处的次数加加就统计出每个元素的次数了。
这样,对于数组count,里面放的元素就是序列a的次数,count的下标就是a的元素。
往出来取元素的过程,就是拿出排序好的序列的过程。每次从数组count里拿出下标,放回去就可以了。如果此时count中的元素大于1,说明排序序列a有重复元素,那我们多拿几次就行了。


代码实现:


#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] << "  ";
    }
    cout << endl;
}


void CountSort(vector<int>& a)
{
    int max = a[0];
    int min = a[0];

    //找出序列的最大值与最小值,开辟max-min+1个空间大小的count数组
    for (int i = 1; i < a.size(); i++)
    {
        if (max<a[i])
            max = a[i];
        if (min>a[i])
            min = a[i];
    }
    int* count = new int[max - min + 1];
    
    memset(count, 0, (max - min + 1) * sizeof(int));//将数组初始化

    /*对要排序的数组a进行个数统计,a数组的元素i就放在count数组的i-min处,
    而不是i处。因为:若序列为1000  2000 3000,开辟的count从下标0开始,就将1000放于count的1000-1000=0处*/
    for (int i = 0; i < a.size(); i++)
    {
        count[a[i]-min]++;
    }

    //将count数组往回去拿,i+min代表还原下标
    int j = 0;
    for (int i = 0; i < max - min + 1; i++)
    {
        while (count[i]>0)//此时该数重复n次,那就将该数拿回去n次
        {
            a[j++] = i + min;
            count[i]--;
        }
        
    }
    
}


void TestCountSort()
{
    vector<int> a = { 12, 34, 12222, 4568, 26, 1, 16, 10, 2, 4, 4, 93, 7, 5, 2, 4 };
    CountSort(a);
    Print(a);
    
}


int main()
{
    TestCountSort();
    system("pause");
    return 0;
}



基数排序:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

#include<assert.h>


void Print(int*  a,int size)
{
    for (int i = 0; i < size; i++)
    {
        cout << a[i] << "  ";
    }
    cout << endl;
}


int MaxRadix(int* a, int size)
{
    int radix = 10;
    int count = 1;
    int i = 0;
    for (int i = 0; i<size; i++)
    {
        while (a[i] > radix)
        {
            radix *= 10;
            count++;
        }
    }
    
    return count;
}


void _PartRadix(int* a, int size,int divisor)
{
    int count[10] = { 0 };

    //处理数组count,统计每个数据的个、十、百等位出现的个数
    for (int i = 0; i < size; i++)
    {
        int num = a[i] / divisor;
        count[num % 10]++;
    }

    //处理数组start,统计每个元素的起始位置
    int start[10] = { 0 };
    for (int i = 1; i < 10; i++)
    {
        start[i] = start[i - 1] + count[i - 1];
    }

    //遍历数组a,将这些元素放在tmp的计算好的位置上
    int* tmp = new int[size];
    for (int i = 0; i < size; i++)
    {
        int num = a[i] / divisor;
        tmp[start[num % 10]++] = a[i];//若该位有重复数,则加加坐标向起始位置的后面放即可
    }

    //拷回个位或十位或百位排序好的数组,开始下一个位的排序
    for (int i = 0; i < size; i++)
    {
        a[i] = tmp[i];
    }
}

void RadixSort(int* a, int size)
{
    assert(a);
    for (int i = 1; i <= MaxRadix(a, size);i++)
    {
        int divisor = 1;//获得除数,便于依次得到数据个位、十位、百位……
        int k = i;
        while (--k)
        {
            divisor *= 10;
        }
        _PartRadix(a, size, divisor);

    }
}

void TestRadixSort()
{
    int a[] = { 12, 34, 12222, 4568, 26, 1, 16, 10, 2, 4, 4, 93, 7, 5, 2, 4 };
    RadixSort(a, sizeof(a) / sizeof(a[0]));
    Print(a,sizeof(a)/sizeof(a[0]));

}


int main()
{
    TestRadixSort();
    system("pause");
    return 0;
}


本文出自 “Han Jing's Blog” 博客,请务必保留此出处http://10740184.blog.51cto.com/10730184/1782077

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

对于比较排序,大家如果感兴趣,可以查看我的博客:http://10740184.blog.51cto.com/10730184/1774508计数排序思路: 我们假设升序排序 排序序列为2000,...
  • cpongo1
  • cpongo1
  • 2016年05月26日 16:32
  • 182

【数据结构】中的计数排序(CountSort)

【数据结构】中的计数排序(CountSort)
  • LX18792732127
  • LX18792732127
  • 2017年05月21日 00:06
  • 268

算法数据结构C++实现4-计数排序(counting sort)

这里是 Introduction to Algorithm 算法导论书中第八章的计数排序 counting sort, 本专题还是以这本书为主,用c++实现其中最重要的算法。 网上也有很多高手研究了这...
  • kenden23
  • kenden23
  • 2013年10月08日 16:08
  • 1732

比快速排序更快的排序--计数排序及其稳定性

假设有一个班级的小学生去操场上体育课,体育老师要求他们按照身高次序站成一队。每个小学生都知道自己的具体身高是多少厘米(假设每个小学生身高都不一样,否则就会为争执位置打架),但每个小学生都不承认别人比自...
  • Justin_bibo
  • Justin_bibo
  • 2017年03月03日 19:09
  • 387

计数排序及其扩展思路

(1)原理和代码以及时间复杂度分析           1.计数排序的原理:设被排序的数组为A,排序后存储到B,C为临时数组。所谓计数,首先是通过一个数组C[i]计算大小等于i的元素个数,此过程只需...
  • NeilHappy
  • NeilHappy
  • 2012年01月15日 13:56
  • 4825

非比较排序——计数排序

对于包括n 个元素的输入序列来说,任何比较排序在最坏情况下都要经过nlg(n) 次比较,因此归并和堆排序是渐进最优的,并且任何已知的比较排序最多就是在常数因子上优于它们。而对于非比较排序来说,下界nl...
  • q745401990
  • q745401990
  • 2013年11月22日 23:26
  • 1174

计数排序及C语言实现

计数排序及C语言实现
  • bing_bing304
  • bing_bing304
  • 2014年11月25日 22:04
  • 938

Java 三种线性排序之计数排序

一.算法说明: 一般的排序都是需要进行关键字的比较的。有没有不需要比较的的呢?有的,计数排序就是其中一种。 计数排序 假设输入序列都是0到k之间的整数,则可使用计数排序。具体操作是这样的:创建一个...
  • lovoo
  • lovoo
  • 2016年07月26日 22:48
  • 762

计数排序和桶排序

介绍两种非基于比较的排序算法。前面提到的排序算法,快排,堆排,合并等都是通过比较元素之间的大小来进行排序的,基于比较的排序是不能突破NLog2NNLog_2N的下界的。而这两种算法的时间复杂度是可以达...
  • u013220338
  • u013220338
  • 2015年04月12日 22:51
  • 382

【算法导论】c++实现计数排序

计数排序的基本思想为:对每一个输入的元素x,确定出小于x的元素的个数。有了这一信息,那么就可以把x直接放到相应的位置上。 特点: 1 需要临时的存储空间,如果排序数据范围特别大时,空间开销很大。 ...
  • Harry_lyc
  • Harry_lyc
  • 2012年07月06日 15:23
  • 2275
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【数据结构】非比较排序的算法实现(包括计数排序、计数排序)
举报原因:
原因补充:

(最多只允许输入30个字)