Java 十大排序算法之计数排序刨析

Java 十大排序算法之计数排序刨析

算法介绍

计数排序是一个时间复杂度为O(n+k)的非基于比较的排序算法,其中n是待排序元素的个数,k是待排序元素的范围,即待排序元素的最大值减去最小值再加1。

算法通过构建一个长度为k的计数数组来统计每个元素出现的次数,然后借助计数数组按顺序输出每个元素,就完成了排序过程。

因为计数排序是非基于比较的算法,因此可以在一定程度上提高排序效率。不过需要注意的是,计数排序只适用于元素范围不大的场景,如果范围过大,统计计数数组可能会占用大量内存,导致性能下降。

算法过程

  1. 统计待排序元素的出现次数,构建一个长度为k的计数数组countArr,遍历待排序数组,将每个元素出现的次数记录在计数数组中;

  2. 计算元素在有序序列中的位置,根据countArr统计出每个元素的前缀和,即sumArr。sumArr[i]表示小于等于i的元素个数;

  3. 将元素按照sumArr的顺序依次放到有序序列sortedArr中,具体操作如下:

  4. 遍历待排序数组,取元素arr[i];

  5. 查找元素arr[i]在计数数组中的出现次数count,即count=countArr[arr[i]];
  6. 将元素arr[i]插入到sortedArr中的位置sumArr[arr[i]]-1,同时将countArr[arr[i]]-1;
  7. 重复以上过程,直到待排序数组arr中的所有元素都被放到sortedArr中。

代码实现

public static void countSort(int[] arr) {
    if (arr == null || arr.length == 0) {
        return;
    }
    int min = arr[0], max = arr[0];
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] < min) {
            min = arr[i];
        } else if (arr[i] > max) {
            max = arr[i];
        }
    }
    int[] countArr = new int[max - min + 1];
    // 统计出现次数
    for (int i = 0; i < arr.length; i++) {
        countArr[arr[i] - min]++;
    }
    // 计算前缀和
    for (int i = 1; i < countArr.length; i++) {
        countArr[i] += countArr[i - 1];
    }
    int[] sortedArr = new int[arr.length];
    for (int i = arr.length - 1; i >= 0; i--) {
        int pos = countArr[arr[i] - min] - 1;
        sortedArr[pos] = arr[i];
        countArr[arr[i] - min]--;
    }
    System.arraycopy(sortedArr, 0, arr, 0, arr.length);
}

示例说明

示例1

int[] arr = {5, 3, 8, 4, 2, 5, 7, 1, 9, 6};
countSort(arr);
Arrays.toString(arr); // [1, 2, 3, 4, 5, 5, 6, 7, 8, 9]

在该示例中,待排序数组arr中的元素最小值为1,最大值为9,因此计数数组countArr的长度为9,记录每个元素出现的次数后,计算前缀和sumArr,然后根据sumArr将元素依次放到sortedArr中。

示例2

int[] arr = {4, 2, 4, 4, 3, 8, 3, 1, 5, 7};
countSort(arr);
Arrays.toString(arr); // [1, 2, 3, 3, 4, 4, 4, 5, 7, 8]

在该示例中,待排序数组arr中的元素最小值为1,最大值为8,因此计数数组countArr的长度为8,记录每个元素出现的次数后,计算前缀和sumArr,然后根据sumArr将元素依次放到sortedArr中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 十大排序算法之计数排序刨析 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • javascript笛卡尔积算法实现方法

    JavaScript笛卡尔积算法实现方法 什么是笛卡尔积 笛卡尔积是指给定多个集合,每个集合中分别选取一个元素组成的所有可能组合的集合。例如,有两个集合 X={1,2} 和 Y={3,4},那么它们的笛卡尔积为 {(1,3), (1,4), (2,3), (2,4)}。 实现笛卡尔积算法 JavaScript实现笛卡尔积算法的过程可以分为以下三步: 遍历所有…

    算法与数据结构 2023年5月19日
    00
  • C++实现合并排序的方法

    C++ 是一门功能强大的编程语言,提供了多种排序算法来满足不同场景的需要。其中,合并排序是一种常用的高效排序算法,下面我们就来介绍一下 C++ 实现合并排序的方法。 合并排序算法简介 合并排序算法是一种基于归并操作的排序算法,它的基本思想是将一个数组划分为两个子数组,递归地对这两个子数组分别进行排序,然后将排好序的两个子数组合并成一个有序的数组。该算法的时间…

    算法与数据结构 2023年5月19日
    00
  • python KNN算法实现鸢尾花数据集分类

    Python实现KNN算法对鸢尾花数据集进行分类 介绍 KNN(K-Nearest-Neighbor)算法是一种非常常用且简单的分类算法之一。它的基本思想是把未知数据的标签与训练集中最邻近的K个数据的标签相比较,得票最多的标签就是未知数据的标签。本文将介绍如何使用Python实现对鸢尾花数据集进行KNN分类。 步骤 加载数据 首先,我们需要加载鸢尾花数据集。…

    算法与数据结构 2023年5月19日
    00
  • c语言排序之归并排序(递归和非递归)

    下面我来为你详细讲解“C语言排序之归并排序(递归和非递归)”的完整攻略: 什么是归并排序 归并排序是一种基于分治策略的排序算法,其基本思想是将原始数据分成若干个小的子序列,然后将这些小的子序列两两合并成为较大的子序列,直到最终合并成为完整的有序序列。 归并排序可以采用递归和非递归两种方式实现。 归并排序递归实现 归并排序的递归实现相对容易理解,可以通过以下步…

    算法与数据结构 2023年5月19日
    00
  • c#实现最简洁的快速排序(你绝对可以看懂)

    下面我将详细讲解“c#实现最简洁的快速排序(你绝对可以看懂)”的完整攻略。 1、什么是快速排序? 快速排序是一种常用的排序算法,其思想是将一个数组划分为两个子数组,然后分别对这两个子数组进行排序。通过不断地递归调用这个过程,最终得到有序的数组。 2、快速排序的步骤 下面是快速排序的步骤: 选择一个基准值(pivot),一般选择数组中的第一个元素。 定义两个指…

    算法与数据结构 2023年5月19日
    00
  • C/C++浅析邻接表拓扑排序算法的实现

    C/C++浅析邻接表拓扑排序算法的实现 什么是拓扑排序 在图论中,若存在一种拓扑序列,使得对于任意的有向边(u,v),u在序列中都在v的前面,则称该图为拓扑排序,该序列称为拓扑序列。拓扑排序是一个有向无环图(DAG, Directed Acyclic Graph)的一种线性序列。 拓扑排序算法的实现 拓扑排序算法的实现一般基于邻接表,其核心思路为:先将所有入…

    算法与数据结构 2023年5月19日
    00
  • c语言快速排序算法示例代码分享

    首先,我们需要了解什么是快速排序。快速排序(QuickSort)是一种排序算法,其采用了分治的思想,并使用递归的方式处理数据集合。它的基本思想是从待排序的数据集合中选择一个元素作为分界点(一般称为pivot),然后将小于pivot的元素放到pivot左边,大于pivot的元素放到pivot右边,最后将pivot放到中间位置。然后递归处理pivot左右两边的子…

    算法与数据结构 2023年5月19日
    00
  • 希尔排序算法的C语言实现示例

    下面是“希尔排序算法的C语言实现示例”完整攻略。 希尔排序算法简介 希尔排序是通过将整个待排序数组分割成多个子序列,对每个子序列进行插入排序,然后逐步减少子序列长度,最终使整个序列有序的一种算法。 希尔排序算法的流程 按照一定的间隔将待排序数组分成若干个子序列; 对每个子序列进行插入排序,使其中的元素可以快速有序; 缩小排序间隔,重复执行步骤1和2; 直至排…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部