9.排序算法
1.冒泡排序
基本介绍:
冒泡排序的基本思想是:通过对待排序序列从前向后(从下标较小的元素开始),一次比较相邻元素的值,如果发现逆序,使较大的元素逐渐从前向后移动。
因为在排序的过程中,各元素不断的接近自己的位置,如果一趟比较下来没有进行任何交换,就说明序列有序。因此要在排序过程中设置一个标志flag,判断元素是否进行交换,从而减少不必要的比较。(后期优化)
示例:
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {11,3, 9, -1, 10, -2};
int count=0;
//冒泡排序
//第一层for循环是循环次数:例如5个数,总共循环5-1=4次
System.out.println("原始数据: "+Arrays.toString(arr));
System.out.println("开始排序------");
for (int i = 0; i < arr.length - 1; i++) {
//第二层for循环,是比较次数
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int num=arr[j];
arr[j]=arr[j+1];
arr[j+1] = num;
}
System.out.println("第"+(count++)+"次排序:"+Arrays.toString( arr));
}
System.out.println("内层排序结束---");
}
}
}
输出:
原始数据: [11, 3, 9, -1, 10, -2]
开始排序------
第0次排序:[3, 11, 9, -1, 10, -2]
第1次排序:[3, 9, 11, -1, 10, -2]
第2次排序:[3, 9, -1, 11, 10, -2]
第3次排序:[3, 9, -1, 10, 11, -2]
第4次排序:[3, 9, -1, 10, -2, 11]
内层排序结束---
第5次排序:[3, 9, -1, 10, -2, 11]
第6次排序:[3, -1, 9, 10, -2, 11]
第7次排序:[3, -1, 9, 10, -2, 11]
第8次排序:[3, -1, 9, -2, 10, 11]
内层排序结束---
第9次排序:[-1, 3, 9, -2, 10, 11]
第10次排序:[-1, 3, 9, -2, 10, 11]
第11次排序:[-1, 3, -2, 9, 10, 11]
内层排序结束---
第12次排序:[-1, 3, -2, 9, 10, 11]
第13次排序:[-1, -2, 3, 9, 10, 11]
内层排序结束---
第14次排序:[-2, -1, 3, 9, 10, 11]
内层排序结束---
结论:发现每次排序都会把最大数放在结尾处!
优化,先看案例:
如果给int arr[] = {1, 2, 3, 5, 4}排序呢
输出:
原始数据: [1, 2, 3, 5, 4]
开始排序------
第0次排序:[1, 2, 3, 5, 4]
第1次排序:[1, 2, 3, 5, 4]
第2次排序:[1, 2, 3, 5, 4]
第3次排序:[1, 2, 3, 4, 5]
内层排序结束---
第4次排序:[1, 2, 3, 4, 5]
第5次排序:[1, 2, 3, 4, 5]
第6次排序:[1, 2, 3, 4, 5]
内层排序结束---
第7次排序:[1, 2, 3, 4, 5]
第8次排序:[1, 2, 3, 4, 5]
内层排序结束---
第9次排序:[1, 2, 3, 4, 5]
内层排序结束---
发现3-9次的排序均一样的,这就是优化的点!
public static void main(String[] args) {
int arr[] = {1, 2, 3, 5, 4};
int count = 0;
//冒泡排序
//第一层for循环是循环次数:例如5个数,总共循环5-1=4次
System.out.println("原始数据: " + Arrays.toString(arr));
System.out.println("开始排序------");
//重点1:表示是否进行过交换
boolean flag = false;
for (int i = 0; i < arr.length - 1; i++) {
//第二层for循环,是比较次数
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int num = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = num;
//重点2:如果发生交换,该字段置为true;
flag = true;
}
System.out.println("第" + (count++) + "次排序:" + Arrays.toString(arr));
}
//内层排序结束后,判断这个字段
//没有进行过交换,直接退出!
if (!flag) {
break;
} else {
//flag=true:进行过交换,这里需要重置下flag,方便下次判断!
flag = false;
}
System.out.println("内层排序结束---");
}
}
输出:发现减少了3次排序
原始数据: [1, 2, 3, 5, 4]
开始排序------
第0次排序:[1, 2, 3, 5, 4]
第1次排序:[1, 2, 3, 5, 4]
第2次排序:[1, 2, 3, 5, 4]
第3次排序:[1, 2, 3, 4, 5]
内层排序结束---
第4次排序:[1, 2, 3, 4, 5]
第5次排序:[1, 2, 3, 4, 5]
第6次排序:[1, 2, 3, 4, 5]
内层排序无法减少,即3-6的排序是无法精简的,因为内层排序是元素一位一位去比较,根本不知道后面元素的大小,两次比较结果相同,并不能说明已经有序:如
本以为这么修改:
//上次排序结果
String str="";
for (int i = 0; i < arr.length - 1; i++) {
//第二层for循环,是比较次数
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int num = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = num;
}
//重点1:比较上次移动和这次的字符串是否一样
if (str.equals(Arrays.toString(arr))) {
break;
}
str=Arrays.toString(arr);
System.out.println("第"+(count++)+"次排序:"+str);
}
System.out.println("内层排序结束---");
}
输出;
原始数据: [1, 2, 3, 5, 4]
开始排序------
第0次排序:[1, 2, 3, 5, 4]
内层排序结束---
结论:
这时还没有有序,内层排序无法减少优化!
效率问题:
因为冒泡排序的事件复杂度为O(n²),所以其事件复杂度会随着n的增大而快速增大!
如果新增80000个随机数,按照冒泡法排序耗时问题:
添加80000个随机数,进行冒泡排序:
public static void main(String[] args) {
int arr[] = new int[80000];
int count = 0;
boolean flag = false;
for (int i=0;i<arr.length; i++){
arr[i]= (int) (Math.random()*arr.length);
}
Date date1=new Date();
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int num = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = num;
flag = true;
}
}
if (!flag) {
break;
} else {
flag = false;
}
}
Date date2=new Date();
System.out.println("结束排序,耗时:"+(date2.getTime()-date1.getTime()));
}
输出:耗时13秒多,
结束排序,耗时:13429
2.选择排序
基本介绍:
选择式排序也属于内部排序法,是从预排序的数据中按照指定的规则选出某一元素,在依次交换位置后达到排序的目的。
选择排序的思想:
选择排序也是一种简单的排序方法,他的基本思想是:
1. 第一次从arr[0]-arr[n-1]中取最小值,与arr[0]交换,
2. 第二次从arr[1] -arr[n-1]中取最小值,与arr[1]交换
3. 第三次从arr[2]-arr[n-1]中取最小值,与arr[2]交换
4.....
5. 第n-1次从arr[n-2]-arr[n-1]中选择最小值,与arr[n-2]交换,
总共交换n-1次,得到一个按照排序从小到大排列的有序序列
public class SelectSort {
public static void main(String[] args) {
int[] arr = {101, 34, 119, 123};
//最小数
int min = 0;
//最小数的下标
int minIndex = 0;
System.out.println("原始:" + Arrays.toString(arr));
for (int i = 0; i < arr.length; i++) {
//这里注意:将最小值和最小下标重新赋值!
min = arr[i];
minIndex = i;
for (int j = i; j < arr.length; j++) {
if (arr[j] < min) {
min = arr[j];
minIndex = j;
}
}
//不相等时,即发生了排序
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
System.out.println("第" + i + "次排序结果:" + Arrays.toString(arr));
}
System.out.println("排序结果:"+Arrays.toString(arr));
}
}
输出:
原始:[101, 34, 119, 123]
第0次排序结果:[34, 101, 119, 123]:发现找到最小值34和第一个元素101互换位置
第1次排序结果:[34, 101, 119, 123]:找到次小值101和第二个元素自己
第2次排序结果:[34, 101, 119, 123]:找到第三小值119
第3次排序结果:[34, 101, 119, 123]
排序结果:[34, 101, 119, 123]
选择排序耗时:
public class SelectSort {
public static void main(String[] args) {
int[] arr = new int[80000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 80000);
}
Date date1=new Date();
sort(arr);
Date date2=new Date();
System.out.println("选择排序耗时:"+(date2.getTime()-date1.getTime()));
System.out.println("排序结果:"+Arrays.toString(arr));
}
/**
* 排序
*
* @param arr 排序数组
*/
public static void sort(int[] arr) {
//最小数
int min = 0;
//最小数的下标
int minIndex = 0;
for (int i = 0; i < arr.length; i++) {
//这里注意:将最小值和最小下标重新赋值!
min = arr[i];
minIndex = i;
for (int j = i; j < arr.length; j++) {
if (arr[j] < min) {
min = arr[j];
minIndex = j;
}
}
//不相等时,即发生了排序
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}
}
测试输出:发现选择排序的耗时要比冒泡排序快了不知道多少!!!
选择排序耗时:2583
排序结果:[0, 1, 1, 1, 2, 2, 3, 5, 6, 7, 9, 9, 10, 11, 12, 14, 14, 15, 15, ....79998]
3.插入排序
简介:
插入式排序处于内部排序法,是对欲排序的元素以插入的方式,找寻该元素的适当位置,以达到排序的目的。3
插入排序的思想:
插入排序的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只有一个元素,无序表中包含n-1个元素,排序过程中每次从无序表中取出一个元素,把它的值和有序表中的值进行比较,将它插入到有序表真娘怪的适当位置,使之成为新的有序表
插入排序代码:
/**
* 插入排序
*/
public class InsertSort {
public static void main(String[] args) {
int[] arr = {17, 3, 1, 4, 20, 9};
System.out.println("原始数据:"+Arrays.toString(arr));
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
/*
插入排序的基本思想是:
1.把n个待排序的元素看成为一个有序表和一个无序表,
2.开始时有序表中只有一个元素,无序表中包含n-1个元素,
3.排序过程中每次从无序表中取出一个元素,把它的值和有序表中的值进行比较,
4.将它插入到有序表真娘怪的适当位置,使之成为新的有序表
*/
int count = 0;
for (int i = 1; i < arr.length; i++) {
//插入的数据
int insertVal = arr[i];
//插入数据的前一列
int insertIndex = i - 1;
//这里的操作是找到插入位置,并将位置后面的收据全部后移一位!
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
System.out.println(Arrays.toString(arr));
}
arr[insertIndex + 1] = insertVal;
System.out.println("第" + (++count) + "次排序:" + Arrays.toString(arr));
}
}
}
输出:
原始数据:[17, 3, 1, 4, 20, 9]
[17, 17, 1, 4, 20, 9]
第1次排序:[3, 17, 1, 4, 20, 9]
[3, 17, 17, 4, 20, 9]
[3, 3, 17, 4, 20, 9]
第2次排序:[1, 3, 17, 4, 20, 9]
[1, 3, 17, 17, 20, 9]
第3次排序:[1, 3, 4, 17, 20, 9]
第4次排序:[1, 3, 4, 17, 20, 9]
[1, 3, 4, 17, 20, 20]
[1, 3, 4, 17, 17, 20]
第5次排序:[1, 3, 4, 9, 17, 20]
[1, 3, 4, 9, 17, 20]
1.
2.
3.
测试速率:
public static void main(String[] args) {
int[] arr = new int[80000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 80000);
}
Date date1=new Date();
sort(arr);
Date date2=new Date();
System.out.println("选择排序耗时:"+(date2.getTime()-date1.getTime()));
System.out.println("排序结果:"+Arrays.toString(arr));
}
输出:
选择排序耗时:1061
排序结果:[0, 1, 1, 2, 2, 3,.....79999]
可以在赋值的地方做个优化:
for (int i = 1; i < arr.length; i++) {
//插入的数据
int insertVal = arr[i];
//插入数据的前一列
int insertIndex = i - 1;
//这里的操作是找到插入位置,并将位置后面的收据全部后移一位!
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
//重点1:这里做个优化,当insertIndex+1=i,即这个数就在合适位置,如
//{1,5,6,9}给9排序时,发现9是合适的位置:insertIndex+1=i,不用替换
if (insertIndex + 1 != i) {
arr[insertIndex + 1] = insertVal;
}
}
4.希尔排序(较快)
介绍:
希尔排序是1959年提出的一种排序算法,希尔排序也是一种插入排序,但是简单的插入排序经过改进之后的一个更高效版本,也称之为缩小增量排序。
思想:
希尔培训是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序,随着一个增量的逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法终止
1.希尔排序时,对有序序列在插入时采用交换法,并测试排序速度。
2.希尔排序时,对有序序列在插入时采用移动法,并测试排序速度。
交换式的希尔排序
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
System.out.println("原始数组为:" + Arrays.toString(arr));
sort(arr);
}
public static void sort(int[] arr) {
int temp = 0;
int count = 0;
/*
1.将数组按照length/2进行分组,对每个分组进行排序,如数组有10个数据,
第一次分5组,每组两个元素,这两个元素进行排序
2.五组排序结束后,在分为2组,即length/2/2,再进行插入排序
3.直到剩余一组后,进行最后一次排序
*/
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
//定义好了分组,gap就是步长,即arr[i]和arr[i+gap]分为一组
//每个分组都循环一次
System.out.println("-------------------------");
for (int i = gap; i < arr.length; i++) {
for (int j = i - gap; j >= 0; j -= gap) {
if (arr[j] > arr[j + gap]) {
temp = arr[j];
arr[j] = arr[j + gap];
arr[j + gap] = temp;
}
}
}
System.out.println("外层排序:" + Arrays.toString(arr));
}
}
}
输出:
原始数组为:[8, 9, 1, 7, 2, 3, 5, 4, 6, 0]
-------------------------
外层排序:[3, 5, 1, 6, 0, 8, 9, 4, 7, 2]
-------------------------
外层排序:[0, 2, 1, 4, 3, 5, 7, 6, 9, 8]
-------------------------
外层排序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1.将元素分为10/2=5组进行循环比较
最里层的for循环类似于冒泡排序,把较大的数移到后面!
速率测试
public static void main(String[] args) {
int[] arr = new int[80000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 80000);
}
Date date1 = new Date();
sort(arr);
Date date2 = new Date();
System.out.println("选择排序耗时:" + (date2.getTime() - date1.getTime()));
System.out.println("排序结果:" + Arrays.toString(arr));
}
输出:
希尔排序耗时:7262
排序结果:[0, 1, 3,...79997]
移位法:
public static void sort2(int[] arr) {
/*
1.将数组按照length/2进行分组,对每个分组进行排序,如数组有10个数据,
第一次分5组,每组两个元素,这两个元素进行排序
2.五组排序结束后,在分为2组,即length/2/2,再进行插入排序
3.直到剩余一组后,进行最后一次排序
*/
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
//从第gap个元素,诸葛对其所在的组进行直接排序
for (int i = gap; i < arr.length; i++) {
int j = i;
int temp = arr[j];
if (arr[j] < arr[j - gap]) {
while (j - gap >= 0 && temp < arr[j - gap]) {
//移动
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
}
}
测试速率:
选择排序耗时:49
希尔结果:[0, 0, 1, 2, ... 79997, 79999]
5.快速排序(很快)
简介:
快速排序是对冒泡排序的一种改进
基本思想:
通过一趟排序。将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据要小,
然后再按次方法对两部分的数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变得有序
逻辑分析:
1.第一次循环
2.第二次循环
3.这时只需要递归中介值前面和后面两个数组,都按照这种方式处理即可
样例代码
public class QuickSort {
public static void main(String[] args) {
int[] arr={19,97,9,17,1,8};
sort(arr, 0, arr.length-1);
System.out.println("排序结果:"+Arrays.toString(arr));
}
public static void sort(int[] arr, int L, int R) {
//当左右索引相同时,排序结束,左边数组普遍右边
if (L >= R) {
return;
}
int left = L, right = R;
int pivot = arr[left];
System.out.println("原始数据:"+Arrays.toString(arr));
while (left < right) {
System.out.println("--------------:中介值:"+pivot);
while (left < right && arr[right] >= pivot) {
right--;
}
if (left < right) {
arr[left] = arr[right];
}
System.out.println(Arrays.toString(arr));
while (left < right && arr[left] <= pivot){
left++;
}
if (left<right){
arr[right]=arr[left];
}
if (left>=right){
arr[left]=pivot;
}
System.out.println(Arrays.toString(arr));
}
sort(arr,L,right-1);
sort(arr,right+1,R);
}
}
测试输出:符合预期
原始数据:[19, 97, 9, 17, 1, 8]
--------------:中介值:19
[8, 97, 9, 17, 1, 8]
[8, 97, 9, 17, 1, 97]
--------------:中介值:19
[8, 1, 9, 17, 1, 97]
[8, 1, 9, 17, 19, 97]
原始数据:[8, 1, 9, 17, 19, 97]
--------------:中介值:8
[1, 1, 9, 17, 19, 97]
[1, 8, 9, 17, 19, 97]
原始数据:[1, 8, 9, 17, 19, 97]
--------------:中介值:9
[1, 8, 9, 17, 19, 97]
[1, 8, 9, 17, 19, 97]
排序结果:[1, 8, 9, 17, 19, 97]
测试速率
public static void main(String[] args) {
int[] arr = new int[80000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 80000);
}
Date date1 = new Date();
sort(arr,0,arr.length-1);
Date date2 = new Date();
System.out.println("选择排序耗时:" + (date2.getTime() - date1.getTime()));
System.out.println("排序结果:" + Arrays.toString(arr));
}
测试输出:
选择排序耗时:34
排序结果:[0, 1, 5, 5, 5, 5, 6, 6, 8, 8, 11,...79998]
6.归并排序
简介:
归并排序是利用归并的思想实现的排序方法,该算法采用经典的分制策略(分治法将问题分成小的问题然后递归求解,而治的阶段将分的阶段得到的各答案"修补"在一起,即分而治之)
代码示例:将归并排序分为两部分
1.分:将数组递归分为独立的个体
2.治:将每个独立的个体排序后再合在一起
/**
* 归并排序
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
mergeSort(arr, 0, arr.length - 1, new int[arr.length]);
}
/**
* 1.分
*
* @param arr
* @param left
* @param right
* @param temp
*/
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int middle = (left + right) / 2;
//向左继续递归
mergeSort(arr, left, middle, temp);
//向右继续递归
mergeSort(arr, middle + 1, right, temp);
merge(arr, left, middle, right, temp);
}
}
/**
* 2.治
*
* @param arr 需要排序的数组
* @param left 数组最左边:原始为0
* @param middle 中间索引:左边数组的末尾
* @param right 数组最右边:原始为arr.length-1
* @param temp 中转数组
*/
public static void merge(int[] arr, int left, int middle, int right, int[] temp) {
//左边索引
int i = left;
//右边索引
int j = middle + 1;
//指向中转数组temp的索引
int t = 0;
/*
1:先把左右两边有序的数据按照规则填充到temp数组中
直到左右两边的有序序列,有一边处理完毕
*/
while (i <= middle && j <= right) {
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t += 1;
i += 1;
} else {
temp[t] = arr[j];
t += 1;
j += 1;
}
}
/*
有一边处理完毕,但是领另外一边有剩余元素
*/
//左边有剩余
while (i <= middle) {
temp[t] = arr[i];
i += 1;
t += 1;
}
//右边有剩余
while (j <= right) {
temp[t] = arr[j];
j += 1;
t += 1;
}
/**
* 将temp数据拷贝到arr中
* 注意不是每次都拷贝所有
*/
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft] = temp[t];
t += 1;
tempLeft += 1;
System.out.println("---------------");
System.out.println(":temp:" + Arrays.toString(temp));
System.out.println(":arr:" + Arrays.toString(arr));
}
}
}
1.
2.
速率测试
public static void main(String[] args) {
int[] arr = new int[80000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 80000);
}
Date date1 = new Date();
mergeSort(arr, 0, arr.length - 1, new int[arr.length]);
Date date2 = new Date();
System.out.println("选择排序耗时:" + (date2.getTime() - date1.getTime()));
System.out.println("排序结果:" + Arrays.toString(arr));
}
输出:
选择排序耗时:24
排序结果:[3, 4, 4..., 79999]
7.基数排序(快速)
介绍
1.基数排序属于分配式排序,又称桶子法,他是通过键值的各个位的值,将要排序的元素分配至某些桶中,达到排序的效果。
2.基数排序法属于稳定性的排序,基数排序法是效率高的稳定性排序法。
3.基数排序是桶排序的扩展。
4.金术培训是1887年,霍尔曼.何乐发明的,他是这样实现:将整数按照位数切割成不同的数字,然后按每一个位数分别比较
思想
1.将所有带比较数值统一为同样的数位长度,数位较短的数前面补零,然后从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列
public class RadixSort {
public static void main(String[] args) {
int[] arr={53,3,542,748,14,214};
System.out.println("原始数组:"+Arrays.toString(arr));
sort(arr);
System.out.println("排序结果:"+ Arrays.toString(arr));
}
public static void sort(int[] arr) {
int count=1;
/*
* 定义一个二维数组
* 1.二维数组包含10个一维数组
* 2,为了防止放入数时,数据溢出,定义一个一位数组,大小为arr.length里面放着二维数组中的数据数量
* 3.基数排序是使用空间换时间的经典算法
*/
int[][] bucket = new int[9][arr.length];
//定义一个一维数组,存放二维数组中数据的大小
int[] bucketElementCounts = new int[10];
/*
1.获取所有元素中最大的数,因为最大的数有记为就循环几次
*/
int maxNum = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > maxNum) {
maxNum = arr[i];
}
}
//循环次数
int cyclesNum = (maxNum + "").length();
for (int i = 0, n = 1; i < cyclesNum; i++, n *= 10) {
/*
注意:例如542
1.当第一次循环取个位数:542%10=2
2.当第二次循环取十位数:(542/10)%10=4
3.当第三次循环取百位数:(542/10/10)%10=5
*/
for (int j = 0; j < arr.length; j++) {
int num = arr[j] / n % 10;
/*
这里细品下
*/
bucket[num][bucketElementCounts[num]] = arr[j];
bucketElementCounts[num]+=1;
}
/*
2.已将数据放入到这10个数组中,现在依次将其拿出放入到arr中即可
*/
int index = 0;
for (int m = 0; m < bucketElementCounts.length; m++) {
if (bucketElementCounts[m] > 0) {
for (int y = 0; y < bucketElementCounts[m]; y++) {
arr[index++] = bucket[m][y];
}
}
/*
3.最后一步,需要将bucketElementCounts的所有元素置为0
*/
bucketElementCounts[m]=0;
}
System.out.println("中间第"+(count++)+"次排序结果:"+Arrays.toString(arr));
}
}
}
输出:
原始数组:[53, 3, 542, 748, 14, 214]
中间第1次排序结果:[542, 53, 3, 14, 214, 748]
中间第2次排序结果:[3, 14, 214, 542, 748, 53]
中间第3次排序结果:[3, 14, 53, 214, 542, 748]
排序结果:[3, 14, 53, 214, 542, 748]
结论:
数组中最大数有几位就循环几次!
速率测试:
public static void main(String[] args) {
int[] arr = new int[80000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 80000);
}
Date date1 = new Date();
sort(arr);
Date date2 = new Date();
System.out.println("选择排序耗时:" + (date2.getTime() - date1.getTime()));
System.out.println("排序结果:" + Arrays.toString(arr));
}
测试输出:
选择排序耗时:34
排序结果:[1, 2, 2, 4,... 79999]