计数排序 C++

计数排序简介

  • 计数排序用于对已知数组元素范围的数组进行排序,要求输入的数据必须是有确定范围的整数
    • 这个算法于1954年由 Harold H. Seward 提出
    • 比如比如100万学生参加高考,对这100万学生的某科成绩(假设分数为整数的0到100)做个排序,计数数组的作用就是0-100分,统计落到每个分数上的学生分别有多少个

计数排序步骤

  • 它创建一个长度为这个数据范围的计数数组C
    • 计数数组计算大小:通过遍历排序数组,得到排序数组中的最大值和最小值,之差就是计数数组的大小
  • C中每个元素记录要排序数组中对应记录的出现个数
    • 遍历排序数组,将其值映射到计数数组中
  • 遍历计数数组,对原数组排序
  • 时间:O(n),空间:O(m),m是原数组最大值与最小值的差,可能是n
#include<iostream>
#include<stdlib.h>//随机数使用
#include<time.h>
#include<vector>
using namespace std;

//a,b是生成随机数的上下限
int a = 0;
int b = 10;
int getMinVal(vector<int>&v){
    //这里应该判断v是否为空,但是为了简单,没有进行判断。
    //需要考虑如果v为空,返回什么值
    int min_val = v[0];
    for(int val:v){
        if(val < min_val)
            min_val = val;
    }
    return min_val;
}
int getMaxVal(vector<int>&v){
    int max_val = v[0];
    for(int val:v){
        if(val > max_val)
            max_val = val;
    }
    return max_val;
}

void CountSort(vector<int>&v){
    //开辟计数数组
    int tmp_size = getMaxVal(v) - getMinVal(v) + 1;//+1不要忘记
    vector<int>cntArr(tmp_size,0);
    //计数数组初始化
    for(int val:v)
        cntArr[val]++;

    //对计数数组从低向高遍历
    //也可以从高向低遍历,此时需要做累加,比如计数数组的最后一个元素代表小于这个下标的元素有多少个
    int index = 0;
    for(int i = 0; i < tmp_size; i++){
        while(cntArr[i] > 0){
            v[index++] = i;
            cntArr[i]--;//这个边界条件不变的话,就会导致死循环等问题
        }
    }
}

int main(){
    srand(unsigned(time(NULL)));//用来产生每次都不同的伪随机数,以时间作为随机种子
    int rand_num;
    vector<int>v;//待排序数组
    cout<<"原数组:";
    for(int i = 0; i < 10; i++){
        rand_num = a+(rand()%(b-a));//[a,b]之间的随机数
        v.push_back(rand_num);//原vector如果初始化了,这里可以直接访问v[i],用push_back是追加,那么初始化的元素都没有变
        cout<<rand_num<<" ";
    }
    CountSort(v);
    cout<<endl<<"排序后数组:";
    for(int val:v)
        cout<<val<<" ";
    return 0;
}

本文参考

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值