算法之计数排序

原理:用一个数组记录待排序数组中出现的数字。
最低位代表最小值,偏移量是记录数组中的下标;
待排序数组: 2 1 4 可以表示为
记录数组: 1 1 0 1 数组长度为(4-1+1)

然后根据记录数组输出结果

 public static void countSort(int [] arr){
        if(arr==null){
            return;
        }
        if(arr.length<=1){
            return;
        }
        int maxValue=getMax(arr);
        int minValue=getMin(arr);

//        创建一个数组来记录出现的数字
        int[] recordArr=new int[maxValue-minValue+1];

//        看一下哪个数字出现了
        for(int i=0;i<arr.length;i++){
            int curNum=arr[i];
//            记录出现的数字以及他出现的次数
            recordArr[curNum-minValue]+=1;
        }

//        输出出现在待排序数组中出现的数字
        int curArrIndex=0;
        int len=arr.length;
        int curRecordIndex=0;


      while (curArrIndex<len){
          if(recordArr[curRecordIndex]>0){
//             该数字在待排序数组中出现
              arr[curArrIndex]=minValue+curArrIndex;
              recordArr[curArrIndex]--;
              curArrIndex++;

          }else {
//              该书在在待排序数组中没有出现
              curRecordIndex++;
          }


      }

    }

//    获取数组中的最大值
    public static int getMax(int [] arr){
        int res=Integer.MIN_VALUE;
        for(int i=0;i<arr.length;i++){
            if(res<arr[i]){
                res=arr[i];
            }
        }
        return res;
    }
//    获取数组中的最小只
    public static int getMin(int []arr){
        int res=Integer.MAX_VALUE;
        for(int i=0;i<arr.length;i++){
            if(res>arr[i]){
                res=arr[i];
            }
        }
        return res;
    }

但上面这种方法,本质上并未对待排序数组进行排序(操作),如果排序的是对象的话,就无法使用,而且也不能解决稳定性问题

解决方法:
在获得记录数组后,更新记录数组,每一位+=前一位,这样一来,记录数组的值-1代表 所记录数字在排序结果中的下标

待排序数组:1 4 2
记录数组:1 1 0 1
更新后: 1 2 2 3

从后面读起:
待排序数组中,2对应位置为下标2-1;4对应下标为3-1;1对应下表为1-1

//进化版计数排序
//    由于初级版本通过记录出现的数字,然后直接输出获得数组,并没有实际操作待排序数组
//    这种排序只能对对象进行排序,并且是不稳定的

    public static void countSort(int[] arr){
        if(arr==null||arr.length<=1){
            return;
        }


        int maxValue=getMax(arr);
        int minValue=getMin(arr);

//        创建一个数组来记录出现的数字
        int[] recordArr=new int[maxValue-minValue+1];

//        看一下哪个数字出现了
        for(int i=0;i<arr.length;i++){
            int curNum=arr[i];
//            记录出现的数字以及他出现的次数
            recordArr[curNum-minValue]+=1;
        }
        
//        更新记录数组
        for(int i=1;i<recordArr.length;i++){
            recordArr[i]+=recordArr[i-1];
        }
        
        int []res=new int[arr.length];
        
        for(int i=arr.length-1;i>=0;i--){
            int curValue=arr[i];
//            获得当前数字的 排序后下标
            int index=recordArr[curValue-minValue]-1;
            recordArr[curValue-minValue]--;
            res[index]=curValue;
        }
        arr=res;
    }

    //    获取数组中的最大值
    public static int getMax(int [] arr){
        int res=Integer.MIN_VALUE;
        for(int i=0;i<arr.length;i++){
            if(res<arr[i]){
                res=arr[i];
            }
        }
        return res;
    }
    //    获取数组中的最小只
    public static int getMin(int []arr){
        int res=Integer.MAX_VALUE;
        for(int i=0;i<arr.length;i++){
            if(res>arr[i]){
                res=arr[i];
            }
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基数排序(Radix Sort)是一种非比较排序算法,它根据元素的大小,将元素分配到不同的桶中进行排序计数排序(Counting Sort)是一种稳定的排序算法,它利用桶的思想,对每个元素出现的次数进行统计,再根据桶的顺序依次输出排序果。 基数排序可以使用计数排序作为其内部排序算法,具体实现步骤如下: 1. 找到最大数,并确定其位数 2. 对所有数按照个位数进行排序,利用计数排序 3. 对所有数按照十位数进行排序,利用计数排序 4. 重复步骤 3,直到所有位数都排完序 下面是使用 C++ 实现基数排序的代码: ```cpp #include <iostream> #include <vector> using namespace std; void countingSort(vector<int>& arr, int exp) { vector<int> count(10, 0); vector<int> output(arr.size()); // 统计每个数位上出现的数字的个数 for (int i = 0; i < arr.size(); i++) { int digit = (arr[i] / exp) % 10; count[digit]++; } // 计算每个数字在输出数组中的位置 for (int i = 1; i < count.size(); i++) { count[i] += count[i - 1]; } // 将元素从输入数组复制到输出数组中,保证稳定性 for (int i = arr.size() - 1; i >= 0; i--) { int digit = (arr[i] / exp) % 10; output[count[digit] - 1] = arr[i]; count[digit]--; } // 将排序好的数组赋值给原数组 for (int i = 0; i < arr.size(); i++) { arr[i] = output[i]; } } void radixSort(vector<int>& arr) { int max_num = *max_element(arr.begin(), arr.end()); // 从个位开始,依次对每个数位进行排序 for (int exp = 1; max_num / exp > 0; exp *= 10) { countingSort(arr, exp); } } int main() { vector<int> arr = { 170, 45, 75, 90, 802, 24, 2, 66 }; radixSort(arr); for (auto num : arr) { cout << num << " "; } return 0; } ``` 输出果为:2 24 45 66 75 90 170 802

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值