排序算法——计算排序算法的实现

1、时间复杂度:o(n);
空间复杂度:o(n+k);
牺牲空间复杂度换取时间复杂度的降低;
2、算法思想:
计数排序局限性比较大,算法思想:假定输入是有一个小范围内的整数构成的(比如年龄等),利用额外的数组去记录元素应该排列的位置,思想比较简单。
计数排序是典型的不是基于比较的排序算法,基于比较的排序算法最少也要O(nlogn),有没有可能创造线性时间的排序算法呢?那就是不基于比较的排序算法;
如果数组的数据范围为0~100,则很适合此算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序
算法步骤:
1、找出待排序的数组中最大和最小的元素
2、统计数组中每个值为i的元素出现的次数,存入数组C的第i项
3、对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
4、反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

实现代码:


/***************************************************************************

 *  @file       main.cpp

 *  @author     MISAYAONE

 *  @date       27  March 2017

 *  @remark     27  March 2017 

 *  @theme      Counting Sort 

 ***************************************************************************/



#include <iostream>

#include <vector>

#include <time.h>

#include <Windows.h>

using namespace std;



void Counting_sort(int a[], size_t n, int k)

{

    //申请额外空间

    int *p = new int[n];

    int *q = new int[k+1];

    for (int i = 0; i < k; ++i)

    {

        q[i] = 0;//q指向的数组所有元素置0

    }



    //保存数组a中每个元素出现的个数,将排序交给了q数组(其顺序在q数组中就是有序的)



    for (int j = 0; j < n; ++j)

    {

        q[a[j]]++ ;

    }





    //将所有计数次数累加

    for (int i = 1; i < k; ++i)

    {

        q[i] = q[i] + q[i-1];

    }





    //将元素重新输入

    for (int i = n-1; i >= 0; --i)

    {

        //次数大小最小为1、数组开始为0

        p[q[a[i]]-1] = a[i];

        q[a[i]]--;

    }



    for (int j = 0; j < n; ++j)

    {

        a[j] = p[j];

    }

    //不要忘了释放分配的空间

    delete []p;

    delete []q;

}



int main(int argc, char **argv)

{

    int a[10] = {2,56,4,2,9,56,3,59,9,16};

    int max = a[0];

    for (int i = 1;i < 10; ++i)

    {

        if (a[i]>max)

        {

            max = a[i];

        }

    }



    Counting_sort(a,10,max+1);//传入max+1是为了让计数的数组从0开始足够大

    for (int i = 0; i < 10; ++i)

    {

        cout<<a[i]<<" ";

    }

    cin.get();

    return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值