Java实现桶排序和基数排序
桶排序代码:
import java.util.Arrays; /**
* 桶排序
* 工作的原理是将数组分到有限数量的桶里
* 每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)
* 桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间O(N)
* 但桶排序并不是比较排序,它不受到O(n log n) 下限的影响
*
* 时间复杂度: O(N+C),其中C=N*(logN-logM)<br />
* 空间复杂度:N+M,M为桶的个数<br />
* 非原址排序<br />
* 稳定性:稳定<br />
*
* 桶排序假设数据会均匀入桶,在这个前提下,桶排序很快!
*/
public class BucketSort { // 根据桶的个数来确定hash函数,这份代码适合桶的个数等于数组长度
static int hash(int element,int max,int length){
return (element * length)/(max+1);
} private static void sort(int[] arr) {
int length = arr.length;
LinkedNode[] bucket = new LinkedNode[length]; // 桶的个数等于length
int max = arr[0]; // 求max
for (int i = 1; i < arr.length; i++) {
if (arr[i]>max) {
max = arr[i];
}
}
// 入桶
for (int i = 0; i < length; i++) {
int value = arr[i]; // 扫描每个元素
int hash = hash(arr[i], max, length); // 桶的下标
if (bucket[hash]==null) {
bucket[hash] = new LinkedNode(value); // 初始化链表
}else {
insertInto(value,bucket[hash],bucket,hash); // 插入链表
}
}
int k = 0; // 记录数组下标
// 出桶,回填arr
for(LinkedNode node:bucket){
if (node!=null) {
while(node!=null){
arr[k++] = node.value;
node = node.next;
}
}
}
} private static void insertInto(int value, LinkedNode head, LinkedNode[] bucket, int hash) {
LinkedNode newNode = new LinkedNode(value);
// 小于头节点,放在头上
if (value<=head.value) {
newNode.next = head;
// 替换头节点
bucket[hash] = newNode;
return ;
}
// 往后找第一个比当前值大的节点,放在这个节点的前面
LinkedNode p = head;
LinkedNode pre = p;
while(p!=null&&value>p.value){
pre = p;
p = p.next;
}
if (p == null) { // 跑到末尾了
pre.next = newNode;
}else { // 插入pre和p之间
pre.next = newNode;
newNode.next = p;
}
} public static void main(String[] args) {
int arr[] = new int[10];
for(int i=0;i<10;i++){
arr[i] = (int) ((Math.random()+1)*10);
}
System.out.println("排序前:"+Arrays.toString(arr));
sort(arr);
System.out.println("排序后:"+Arrays.toString(arr));
}
} /**
* 简单单向链表的节点
*
*/
class LinkedNode { public int value;
public LinkedNode next; public LinkedNode(int value) {
this.value = value;
} }
桶排序结果:
基数排序代码:
import java.util.ArrayList;
import java.util.Arrays; /**
* 思路:初始化0-9号十个桶,按个位数字,将关键字入桶,入完后,依次遍历10个桶,按检出顺序回填到数组中
* 然后取十位数字将关键字入桶,入完后,依次遍历10个桶,按检出顺序回填到数组中,假如数组中最大的数为三位数,
* 那么再将百位数字作关键字入桶,这样就能实现基数排序了
* 时间复杂度: 假设最大的数有k位,就要进行k次入桶和回填,每次入桶和回填是线性的,所以整体复杂度为kN,
* 其中k为最大数的10进制位数
* 空间复杂度:桶是10个,10个桶里面存n个元素,这些空间都是额外开辟的,所以额外的空间是N+k,k是进制
* 非原址排序
* 稳定性:假设有相等的元素,它们会次第入桶,次第回数组,不会交叉,所以是稳定的<br />
*/
public class RadixSort {
// 10个桶,每个桶装的数个数不定,适合用数组加ArrayList
private static ArrayList[] bucket = new ArrayList[10]; // 初始化桶
static{
for (int i = 0; i < bucket.length; i++) {
bucket[i] = new ArrayList();
}
} /**
* 将数组arr,按d这个位来分配和收集
*
* @param arr
* @param d
* 位数
*/
private static void sort(int[] arr, int d) {
// 全部入桶
for (int i = 0; i < arr.length; i++) {
putInBucket(arr[i], getDigitOn(arr[i], d));
} /*---每个桶中的元素依次压入原数组---*/
int k = 0;
for (int j = 0; j < bucket.length; j++) {// 每个桶
for (Object m : bucket[j]) {
arr[k++] = (Integer) m;
}
} // 记得清空
clearAll();
} private static void putInBucket(int data, int digitOn) {
switch (digitOn) {
case 0:bucket[0].add(data); break;
case 1:bucket[1].add(data); break;
case 2:bucket[2].add(data); break;
case 3:bucket[3].add(data); break;
case 4:bucket[4].add(data); break;
case 5:bucket[5].add(data); break;
case 6:bucket[6].add(data); break;
case 7:bucket[7].add(data); break;
case 8:bucket[8].add(data); break;
default:bucket[9].add(data);break;
}
} private static void clearAll() {
// 对每个桶调用clear方法进行情况
for (ArrayList b : bucket) {
b.clear();
}
} public static void sort(int[] arr) {
int d = 1;// 入桶依据的位初始化为1
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
} // 最大值 int dNum = 1;// 最大数据的位数
while (max / 10 != 0) {
dNum++;
max /= 10;
} while (d <= dNum) {
// 依据第二个参数入桶和出桶
sort(arr, d++);
}
} public static int getDigitOn(int src, int d) {
return src / (int) (Math.pow(10, d - 1)) % 10;
}
public static void main(String[] args) {
int arr[] = new int[10];
for(int i=0;i<10;i++){
arr[i] = (int) ((Math.random()+1)*10);
}
System.out.println("排序前:"+Arrays.toString(arr));
sort(arr);
System.out.println("排序后:"+Arrays.toString(arr));
} }
基数排序结果:
Java实现桶排序和基数排序的更多相关文章
- 由Maximum Gap,对话桶排序,基数排序和统计排序
一些非比较排序 在LeetCode中有个题目叫Maximum Gap.是求一个非排序的正数数列中按顺序排列后的最大间隔.这个题用桶排序和基数排序都能够实现.以下说一下桶排序.基数排序和计数排序这三种非 ...
- 排序基础之非比较的计数排序、桶排序、基数排序(Java实现)
转载请注明原文地址: http://www.cnblogs.com/ygj0930/p/6639353.html 比较和非比较排序 快速排序.归并排序.堆排序.冒泡排序等比较排序,每个数都必须和其他 ...
- 桶排序与基数排序代码(JAVA)
桶排序 publicstaticvoid bucketSort(int[] a,int max){ int[] buckets; if(a==null || m ...
- Python线性时间排序——桶排序、基数排序与计数排序
1. 桶排序 1.1 范围为1-M的桶排序 如果有一个数组A,包含N个整数,值从1到M,我们可以得到一种非常快速的排序,桶排序(bucket sort).留置一个数组S,里面含有M个桶,初始化为0.然 ...
- java-数组排序--计数排序、桶排序、基数排序
计数排序引入 不难发现不论是冒泡排序还是插入排序,其排序方法都是通过对每一个数进行两两比较进行排序的,这种方法称为比较排序,实际上对每个数的两两比较严重影响了其效率,理论上比较排序时间复杂度的最低下限 ...
- java,桶排序,冒泡排序,快速排序
1.桶排序: 百度百科:桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里.每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排 ...
- Java算法 -- 桶排序
桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里.每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序).桶排序是鸽巢排序 ...
- Java实现桶排序
public class BucketSort { public static void main(String[] args) { int[] list = {1000, 192, 221, 12, ...
- 记数排序 & 桶排序 & 基数排序
为什么要写这样滴一篇博客捏...因为一个新初一问了一道水题,结果就莫名其妙引起了战斗. 然后突然发现之前理解的桶排序并不是真正的桶排序,所以写一篇来区别下这三个十分相似的排序辣. 老年菜兔的觉醒!!! ...
随机推荐
- iOS 仿抖音 视频裁剪
1.最近做短视频拍摄.其中的裁剪界面要做得和抖音的视频裁剪效果一样 需求: 裁剪有一个最大裁剪时间.最小裁剪时间.左右拖动可以实时查看对应的视频画面.拖动进度条也能查看对应的画面 .拖动底部视图也能 ...
- caffe服务器搭建血泪记录
装过很多次caffe了,但这个还是遇到了很多奇葩问题,不过以前都是在ubuntu上,这次是在centos上. 1.import error _caffe.so: undefined symbol: ...
- Lesson 1-1
1.1常见难记的几种运算符 1.1.1 除运算 ‘/’ 除运算的结果为小数,即浮点数. >>> 10/3 3.3333333333333335 >>> 10/2 5 ...
- 使用HDFS完成wordcount词频统计
任务需求 统计HDFS上文件的wordcount,并将统计结果输出到HDFS 功能拆解 读取HDFS文件 业务处理(词频统计) 缓存处理结果 将结果输出到HDFS 数据准备 事先往HDFS上传需要进行 ...
- 《剑指offer》翻转单词顺序列
本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:
- git 工作总计
# git 工作总计 1 首先先克隆了git地址 master 分子 (这个做一次) 以后循环做的 2:git checkout -b dev 创建了临时开发的dev 分子 3:修改dev 分子的数据 ...
- Continuity of arithmetic operations
Arithmetic operations taught in elementary schools are continuous in the high level topological poin ...
- gethostbyname
SYNOPSIS #include <netdb.h> struct hostent *gethostbyname(const char *name); Data Structure ht ...
- SpringBoot中对于异常处理的提供的五种处理方式
1.自定义错误页面 SpringBoot 默认的处理异常机制:SpringBoot默认的已经提供了一套处理异常的机制.一旦程序中出现了异常,SpringBoot会向/error的url发送请求.在Sp ...
- Linux从入门到进阶全集——【第八集:软件包管理:rpm、tar、yum】
1,对Linux下软件的了解 源码包:未编译,要编译安装. 二进制包:已编译,可直接安装. 2,centos和ubuntu下的软件包对比: [centos]rpm文件手动安装,使用rpm指令 ...