Java计数排序知识点(含面试大厂题含源码)

news/2024/5/14 23:05:48

计数排序(Counting Sort)是一种线性时间复杂度的排序算法,适用于整数数据。它的基本思想是将输入的数据值转化为键存储在额外开辟的数组空间中。计数排序不是基于比较的排序算法,因此它可以突破 O(nlogn) 的时间下界,实现线性时间排序。

算法原理

计数排序的工作原理如下:

  1. 找出待排序数组的最大值和最小值:确定统计数组的长度(最大值与最小值之差+1)。
  2. 初始化统计数组:创建一个长度为最大值与最小值之差+1的新数组,并将其所有元素初始化为0。
  3. 统计频率:遍历待排序数组,对于每个元素,统计其出现的次数,更新到统计数组对应的位置。
  4. 根据计数得到排序结果:遍历统计数组,按照顺序将元素放置到结果数组中。对于统计数组中每个位置的值,表示待排序数组中该位置元素出现的次数,将该元素重复放置到结果数组相应位置的次数。

算法实现

以下是计数排序的Java实现示例:

public class CountingSortExample {public static void main(String[] args) {int[] arr = {4, 2, 2, 8, 3, 3, 1, 0};countingSort(arr);System.out.println("Sorted array: ");for (int i : arr) {System.out.print(i + " ");}}public static void countingSort(int[] arr) {if (arr == null || arr.length == 0) {return;}// 找出数组的最大值和最小值int max = Arrays.stream(arr).max().getAsInt();int min = Arrays.stream(arr).min().getAsInt();// 初始化计数数组int range = max - min + 1;int[] count = new int[range];for (int i = 0; i < arr.length; i++) {count[arr[i] - min]++;}// 根据计数数组得到排序结果int index = 0;for (int i = 0; i < count.length; i++) {while (count[i] > 0) {arr[index++] = i + min;count[i]--;}}}
}

算法适用性

计数排序适用于以下场景:

  1. 待排序数组中的元素是整数,且范围不是很大。
  2. 待排序数组中的元素重复次数较多,且分布较为集中。

算法优缺点

优点

  1. 计数排序可以实现线性时间复杂度 O(n+k),其中 n 是待排序数组的长度,k 是数组中的最大值与最小值之差。
  2. 排序过程中不需要元素之间的比较操作,适合于比较成本较高的情况。

缺点

  1. 计数排序需要额外的空间来存储计数数组,空间复杂度较高。
  2. 当元素个数非常大时,计数排序可能需要较长的预处理时间和额外空间。

计数排序是一种简单且高效的排序算法,特别适合于特定场景。在实际应用中,可以根据数据的特点和需求来选择是否使用计数排序。

题目 1:基本计数排序

描述
给定一个整数数组 arr,你需要使用计数排序算法对其进行升序排序。

要求

  • 不使用任何现成的排序库或函数。
  • 考虑数组中可能包含的负数。

示例
输入:[-2, 0, 2, 2, 3, 3, 4, 5, -1]
输出:[-2, -1, 0, 2, 2, 3, 3, 4, 5]

Java 源码

import java.util.Arrays;public class CountingSortExample1 {public static void main(String[] args) {int[] arr = {-2, 0, 2, 2, 3, 3, 4, 5, -1};countingSort(arr);System.out.println("Sorted array: " + Arrays.toString(arr));}public static void countingSort(int[] arr) {if (arr == null || arr.length == 0) {return;}int max = Arrays.stream(arr).max().getAsInt();int min = Arrays.stream(arr).min().getAsInt();int range = max - min + 1;int[] count = new int[range];Arrays.fill(count, 0);for (int num : arr) {count[num - min]++;}int index = 0;for (int i = 0; i < count.length; i++) {while (count[i] > 0) {arr[index++] = i + min;count[i]--;}}}
}

题目 2:限制范围内的计数排序

描述
给定一个整数数组 arr 和一个范围 [min, max],你需要使用计数排序算法对数组中在该范围内的元素进行排序,范围外的元素保持不变。

要求

  • 只对给定范围内的元素进行计数排序。
  • 保持原数组中元素的相对顺序。

示例
输入:[-5, -2, 0, 2, 4, 6, 7, 8, 1],范围 1, 5
输出:[-5, -2, 1, 2, 4, 5, 6, 7, 8]

Java 源码

public class CountingSortExample2 {public static void main(String[] args) {int[] arr = {-5, -2, 0, 2, 4, 6, 7, 8, 1};int min = 1;int max = 5;countingSort(arr, min, max);System.out.println("Sorted array: " + Arrays.toString(arr));}public static void countingSort(int[] arr, int min, int max) {if (arr == null || arr.length == 0) {return;}int range = max - min + 1;int[] count = new int[range];Arrays.fill(count, 0);for (int num : arr) {if (num >= min && num <= max) {count[num - min]++;}}int index = 0;for (int i = 0; i < count.length; i++) {while (count[i] > 0) {if (index < arr.length && arr[index] == (i + min)) {index++;} else {arr[index++] = i + min;count[i]--;}}}}
}

题目 3:多位数计数排序

描述
给定一个非负整数数组 arr,你需要使用计数排序算法对其进行按位排序。首先按照个位数排序,然后按照十位数排序,以此类推,直到所有位数都排序完成。

要求

  • 排序过程中保持相同位数的数字的相对顺序。
  • 不使用除法和乘法操作。

示例
输入:[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
输出:[1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

Java 源码

import java.util.Arrays;public class CountingSortExample3 {public static void main(String[] args) {int[] arr = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};multiDigitCountingSort(arr);System.out.println("Sorted array: " + Arrays.toString(arr));}public static void multiDigitCountingSort(int[] arr) {int n = arr.length;int[] count = new int[10];int[] output = new int[n];int exp = 1; // 10^0while (exp < n) {// 计算频率数组Arrays.fill(count, 0);for (int i = 0; i < n; i++) {int digit = (arr[i] / exp) % 10;count[digit]++;}// 累计频率for (int i = 1; i < 10; i++) {count[i] += count[i - 1];}// 根据频率数组得到排序结果for (int i = n - 1; i >= 0; i--) {int digit = (arr[i] / exp) % 10;output[count[digit] - 1] = arr[i];count[digit]--;}// 将输出数组复制回原数组,并更新expSystem.arraycopy(output, 0, arr, 0, n);exp *= 10;}}
}

这些题目和代码示例可以帮助你更好地理解和掌握计数排序算法,以及如何在实际问题中应用这一算法。在面试中,你可能会遇到类似的问题,希望这些示例能够帮助你做好准备。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.tangninghui.cn.cn/item-12761.htm

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

2024春算法训练4——函数与递归题解

一、前言 感觉这次的题目都很好&#xff0c;但是E题....&#xff08;我太菜了想不到&#xff09;&#xff0c;别人的题解都上百行了&#xff0c;晕&#xff1b; 二、题解 A-[NOIP2010]数字统计_2024春算法训练4——函数与递归 (nowcoder.com) 这种题目有两种做法&#xff1a;…

什么是GIF?MP4视频如何转换成GIF动图格式?

一&#xff0c;什么是GIF GIF的全称是Graphics Interchange Format&#xff0c;可译为图形交换格式&#xff0c;用于以超文本标志语言&#xff08;Hypertext Markup Language&#xff09;方式显示索引彩色图像&#xff0c;在因特网和其他在线服务系统上得到广泛应用。GIF是一种…

opencv图像处理技术(阈值处理与图像平滑)

进行图像处理时&#xff0c;常常需要对图像进行预处理以提取所需的信息或改善图像质量。阈值处理和图像平滑是两种常见的预处理技术。 阈值处理 阈值处理是一种图像分割技术&#xff0c;其基本思想是将图像中的像素值与一个或多个预先设定的阈值进行比较&#xff0c;根据比较…

基于SpringBoot和Vue的校园周边美食探索以及分享系统

今天要和大家聊的是基于SpringBoot和Vue的校园周边美食探索以及分享系统 &#xff01;&#xff01;&#xff01; 有需要的小伙伴可以通过文章末尾名片咨询我哦&#xff01;&#xff01;&#xff01; &#x1f495;&#x1f495;作者&#xff1a;李同学 &#x1f495;&#x1f…

微信小程序实现滚动标签

使用scroll-view标签可实现组件滚动标签 1、list中 list.wxml代码如下: <!--pages/list/list.wxml--> <navigation-bartitle"小程序" back"{{false}}"color"black" background"#FFF"></navigation-bar><scroll-…

设置模式——备忘录模式

备忘录模式 备忘录模式&#xff08;Memento Design Pattern&#xff09;&#xff0c;也叫快照&#xff08;Snapshot&#xff09;模式。指在不违背封装原则前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态&#xff0c;以便之后恢复对象为先前…