当前位置: 首页 > article >正文

Java算法之计数排序(Counting Sort)

简介

计数排序是一种线性时间复杂度的排序算法,它不依赖于元素之间的比较,而是通过统计数组中每个元素出现的次数,然后根据这些统计信息对元素进行排序。这种算法特别适用于整数且整数的范围不是非常大时。

算法步骤

  1. 找出数组中的最大值。
  2. 创建一个计数数组,长度为最大值加一。
  3. 遍历原数组,对每个元素在计数数组中对应的位置加一。
  4. 再次遍历计数数组,将每个非零元素按顺序累加到原数组。
//countingSort 方法接受数组和最大值作为参数,执行计数排序。
//首先创建一个计数数组,长度为最大值加一。
//遍历原数组,统计每个元素出现的次数。
//再次遍历计数数组,将非零元素累加到原数组。
//main 方法中,我们初始化一个数组,找出最大值,然后调用 countingSort 方法进行排序,并打印排序后的结果。
public class CountingSort {
    // 计数排序方法
    public static void countingSort(int[] arr, int maxVal) {
        int n = arr.length;
        int[] count = new int[maxVal + 1]; // 创建计数数组

        // 统计每个元素出现的次数
        for (int i = 0; i < n; i++) {
            count[arr[i]]++;
        }

        // 将计数数组中非零元素累加到原数组
        int index = 0;
        for (int i = 0; i < count.length; i++) {
            while (count[i] > 0) {
                arr[index++] = i;
                count[i]--;
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {4, 2, 2, 8, 3, 3, 1};
        int maxVal = getMaxVal(arr); // 找出数组中的最大值

        countingSort(arr, maxVal);

        // 打印排序后的数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    // 辅助方法,找出数组中的最大值
    private static int getMaxVal(int[] arr) {
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }
}

优点

  • 时间效率:对于小范围整数排序,计数排序的时间复杂度是O(n+k),其中n是数组长度,k是整数的范围。
  • 稳定性:计数排序是稳定的排序算法,相等元素的相对位置不会改变。
  • 简单性:算法逻辑简单,容易实现。

缺点

  • 空间复杂度:计数排序需要额外的存储空间,其大小取决于整数的范围,空间复杂度为O(k)。
  • 适用范围:只适用于整数排序,对于非整数或整数范围非常大的情况,效率不高。

时间复杂度和空间复杂度分析

  • 时间复杂度:O(n+k),其中n是数组长度,k是整数的范围。
  • 空间复杂度:O(k),需要一个大小为k的计数数组。

使用场景

  • 当整数的范围k远小于数组长度n时,计数排序非常高效。
  • 适用于对固定范围的整数进行排序,如统计字符出现次数。

http://www.kler.cn/a/286413.html

相关文章:

  • vscode+WSL2(ubuntu22.04)+pytorch+conda+cuda+cudnn安装系列
  • Python练习(2)
  • Hive:Hive Shell技巧
  • uniapp使用uni.navigateBack返回页面时携带参数到上个页面
  • K8S 快速实战
  • 解读隐私保护工具 Fluidkey:如何畅游链上世界而不暴露地址?
  • Jenkins安装使用详解,jenkins实现企业级CICD流程
  • 解除 Excel 表格的文档保护全攻略
  • OceanbaseV4模拟题解析
  • C语言典型例题58
  • Java的动态代理(实际案例秒懂!)
  • 【Unity】简单机甲运动系统——坦克式操控方式
  • 前后端分离的security角色权限实现
  • 在 macOS 上升级 Ruby 版本的几种方法
  • Linux 常用命令 - hexdump 【以指定格式显示文件内容】
  • 【UE5】控件蓝图——树视图(TreeView)的基本使用
  • 2024国赛数学建模备战:灰色预测,国赛数学建模思路代码 模型
  • hive学习(六)
  • 【大模型】GPT系列模型基础
  • 讯鹏科技智慧公厕专业供应商,解读智慧公厕有哪些奥秘
  • 【Spring Boot 3】【Web】文件下载
  • 盘点2024年4款可以免费使用的视频压缩软件。
  • 如何打造Java SpringBoot宿舍设备管理系统,全程跟踪设备使用周期,2025最新设计指南
  • 量化投资策略与技术学习PART8:量化选股之趋势追踪
  • 【数据结构】二叉树基础(带你详细了解二叉树)
  • GPU服务器与CPU服务器的不同之处