Java实现基于桶式排序思想和计数排序思想实现的基数排序

计数排序

  前提:待排序表中的所有待排序关键字必须互不相同;

  思想:计数排序算法针对表中的每个记录,扫描待排序的表一趟,统计表中有多少个记录的关键码比该记录的关键码小,假设针对某一个记录,统计出的计数值为c,则该记录在新的有序表中的存放位置即为c。

  性能:空间复杂度:o(n);时间复杂度:o(n^2);

 1   public int[] countSort(int[] array){
 2         int[] tempArray = new int[array.length];  //引入辅助数组
 3         for(int i=0;i<array.length;i++){
 4             int count = 0;
 5             for(int j=0;j<array.length;j++){
 6                 if(array[i]>array[j]){
 7                     count++;
 8                 }
 9             }
10             tempArray[count] = array[i];
11         }
12         return tempArray;
13     }

桶式排序

  桶式排序需要待排序的序列满足以下两个特征:

    待排序列所有的值处于一个可枚举的范围之类;

    待排序列所在的这个可枚举的范围不应该太大,否则排序开销太大。  

  排序的具体步骤如下:

    (1)对于这个可枚举范围构建一个buckets数组,用于记录“落入”每个桶中元素的个数;

    (2)将(1)中得到的buckets数组重新进行计算,按如下公式重新计算:

buckets[i] = buckets[i] +buckets[i-1] (其中1<=i<buckets.length);
 1    public static void bucketSort(int[] data) {
 2         //得到待排序元素中的最大值和最小值
 3         int max=data[0],min=data[0];
 4         for(int i=1;i<data.length;i++){
 5             if(data[i]>max){
 6                 max = data[i];
 7             }
 8             if(data[i] < min){
 9                 min = data[i];
10             }
11         }
12
13         // 缓存数组
14         int[] tmp = new int[data.length];
15         // buckets用于记录待排序元素的信息
16         // buckets数组定义了max-min+1个桶
17         int[] buckets = new int[max-min+1];
18         // 计算每个元素在序列出现的次数
19         for (int i = 0; i < data.length; i++) {
20             buckets[data[i] - min]++;
21         }
22         // 计算“落入”各桶内的元素在有序序列中的位置
23         for (int i = 1; i < max - min; i++) {
24             buckets[i] = buckets[i] + buckets[i - 1];
25         }
26         // 将data中的元素完全复制到tmp数组中
27         System.arraycopy(data, 0, tmp, 0, data.length);
28         // 根据buckets数组中的信息将待排序列的各元素放入相应位置
29         for (int k = data.length - 1; k >= 0; k--) {
30             data[--buckets[tmp[k] - min]] = tmp[k];
31         }
32     }  

基于桶式排序思想和计数排序思想实现基数排序:

  将待排序元素中的每组关键字依次进行桶分配。

 1   public int[] radixSortBuckets(int[] array, int radix) {
 2         // 找到待排序序列中的最大元素
 3         int max = array[0];
 4         for (int i = 1; i < array.length; i++) {
 5             if (array[i] > max) {
 6                 max = array[i];
 7             }
 8         }
 9         // 确定最大元素的位数maxBits
10         int maxBits = 0;
11         while (max > 0) {
12             max = max/10;
13             maxBits++;
14         }
15
16         int[] tempArray = new int[array.length];  //用于暂存元素
17         int[] buckets = new int[radix];  //用于桶式排序
18         int rate = 1;
19         // 进行maxBits次分配和收集
20         for(int i=0; i< maxBits;i++){
21             // 将array中的元素完全复制到arrayTemp数组中
22             System.arraycopy(array, 0, tempArray, 0, array.length);
23             Arrays.fill(buckets, 0); // 重置buckets数组
24
25             //分配:计算每个待排序元素的子关键字,并将其次数加到对应的桶中
26             for(int j=0;j<tempArray.length;j++){
27                 buckets[(tempArray[j]/rate)%radix] ++;
28             }
29             // 计算“落入”各桶内的元素在有序序列中的位置
30             for(int k=1;k<buckets.length;k++){
31                 buckets[k] = buckets[k]+buckets[k-1];
32             }
33
34             // 收集:按子关键字对指定的数据进行排序
35             for(int m=tempArray.length-1;m>=0;m--){
36                 int subKey = (tempArray[m]/rate)%radix;
37                 array[--buckets[subKey]] = tempArray[m];
38             }
39
40             rate *= radix;
41         }
42         return array;
43     }
时间: 2024-11-02 14:35:47

Java实现基于桶式排序思想和计数排序思想实现的基数排序的相关文章

算法导论之六:线性时间排序之 决策树&amp;计数排序

本系列前五篇都是讲述的比较排序算法,从本文开始,将进入线性时间排序.什么是比较排序,简单的说,就是排序的过程依赖于数组中数据大小的比较,从而来确定数据在排好序输出时的位置. 比较排序法比较直观,但是也有它的不足,我们容易证明任何比较排序法,在最坏的情况下的时间复杂度的下限都是 nlgn.要证明这个问题,我们首先要搞清楚一个模型:决策树模型. 一.决策树模型 什么是决策树?决策树从形态上来讲,是一颗完全二叉树,它除叶子节点之外,其他层的节点都是满的.它的每一个叶子节点表示对输入数据组合的一种排序可

基本排序系列之计数排序

简述计数排序 看了好多别人写的计数排序,看了好久都没看懂,弄了好久最后发现这么简单居然花了几个小时,所以在这里写上,希望和我一样的初学者不会再绕弯路. 一.简述计数排序的思想: 设被排序的数组为A,排序后存储到B,C为临时数组.所谓计数,首先是通过一个数组C[i]计算大小等于i的元素个数,此过程只需要一次循环遍历就可以:在此基础上,计算小于或者等于i的元素个数,也是一重循环就完成.下一步是关键:逆序循环,从length[A]到1,将A[i]放到B中第C[A[i]]个位置上.原理是:C[A[i]]

排序算法之计数排序

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

常见排序算法之计数排序与基数排序

1.计数排序 顾名思义,是对待排序数组中的数据进行统计,然后根据统计的数据进行排序,例如: 待排序数组: a[] = { 100, 123, 112, 123, 201, 123, 112, 156, 156, 178, 185, 156, 123, 112 } 首先取出数组中最大值与最小值(这个不用说了吧) 最大值:201  最小值:100 因此该数组的数值范围为 201 - 100 + 1 = 102 开辟一个大小为102的数组 count[102] 并将所有元素初始化为0 再次遍历数组,以

非基于比较的排序算法之一:计数排序

计数排序(Counting sort)是一种稳定的排序算法.计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值小于等于i的元素的个数.然后根据数组C来将A中的元素排到正确的位置. 限制:所有值得取值范围不能太大,并且需要知道确切的取值范围.本算法需要的辅助空间要求较高. 当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k).计数排序不是比较排序,排序的速度快于任何比较排序算法. 现在给出C#实现的计数排序(counting sort) public vo

三种线性排序算法(计数、基数、桶排序)的简单实现

一.计数排序 计数排序假设n个输入元素中的每一个都是介于0到k之间的整数.此处k为某个整数(输入数据在一个小范围内). 基本思想: 计数排序的基本思想是对每一个输入元素x,确定出小于x的元素的个数.然后再将x直接放置在它在最终输出数组中的位置上. 如下图所示: 由于数组中可能有相等的数,在处理时需要注意. 时间复杂度和空间复杂度分析 算法总时间Θ(k + n).当k=O(n)时,计数排序的运行时间是Θ(n). 空间复杂度是O(n+k).需要两个辅助数组:存放排序结果的数组B[n],存放临时结果的

常见的排序算法(四)( 归并排序,计数排序 , 基数排序)

 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. (如果读者不太了解什么叫分治法,可以去看看<算法导论>第一二章.) 归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1:否则将第

【算法】计数排序、桶排序和基数排序详解

01.计数排序.桶排序与基数排序 并不是所有的排序 都是基于比较的,计数排序和基数排序就不是.基于比较排序的排序方法,其复杂度无法突破\(n\log{n}\) 的下限,但是 计数排序 桶排序 和基数排序是分布排序,他们是可以突破这个下限达到O(n)的的复杂度的. 1. 计数排序 概念 计数排序是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C,使用 C[i] 来计算 i 出现的次数.然后根据数C来将原数组A中的元素排到正确的位置. 复杂度 计数排序的最坏时间复杂度.最好时间复杂度.平均时

排序算法下——桶排序、计数排序和基数排序

桶排序.计数排序和基数排序这三种算法的时间复杂度都为 $O(n)$,因此,它们也被叫作线性排序(Linear Sort).之所以能做到线性,是因为这三个算法是非基于比较的排序算法,都不涉及元素之间的比较操作. 1. 桶排序(Bucket Sort)? 1.1. 桶排序原理 桶排序,顾名思义,要用到"桶".核心思想是将要排序的数据分到几个有序的桶里,每个桶的数据再单独进行排序.桶内排完序后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了. 1.2. 桶排序的时间复杂度分析 如