零、简介
1. 排序与十大排序算法
排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
排序算法是《数据结构与算法》中最基本的算法之一。
八大排序算法指的是《数据结构与算法》中介绍的冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、基数排序,十大排序则是在此基础上加上计数排序和桶排序。
排序算法可以分为内部排序和外部排序:
- 内部排序:所有排序操作都在内存中完成,不需要额外的磁盘或其他存储设备的辅助。这适用于数据量小到足以完全加载到内存中的情况。
- 外部排序:当数据量过大,不可能全部加载到内存中时使用。外部排序通常涉及到数据的分区处理,部分数据被暂时存储在外部磁盘等存储设备上。
排序算法具有稳定和不稳定两种性质:
- 稳定:如果 A 原本在 B 前面,而 A=B,排序之后 A 仍然在 B 的前面。
- 不稳定:如果 A 原本在 B 的前面,而 A=B,排序之后 A 可能会出现在 B 的后面。
2. 排序算法类别
3.十大排序算法特征
排序算法 | 时间复杂度(平均) | 时间复杂度(最差) | 时间复杂度(最好) | 空间复杂度 | 排序方式 | 稳定性 |
---|---|---|---|---|---|---|
冒泡排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | O ( n ) O(n) O(n) | O ( 1 ) O(1) O(1) | 内部排序 | 稳定 |
选择排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | $O(n^2) | O ( 1 ) O(1) O(1) | 内部排序 | 不稳定 |
插入排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | O ( n ) O(n) O(n) | O ( 1 ) O(1) O(1) | 内部排序 | 稳定 |
希尔排序 | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n 2 ) O(n^2) O(n2) | O ( n l o g n ) O(nlogn) O(nlogn) | O ( 1 ) O(1) O(1) | 内部排序 | 不稳定 |
归并排序 | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n ) O(n) O(n) | 外部排序 | 稳定 |
快速排序 | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n 2 ) O(n^2) O(n2) | O ( n l o g n ) O(nlogn) O(nlogn) | O ( l o g n ) O(logn) O(logn) | 内部排序 | 不稳定 |
堆排序 | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n l o g n ) O(nlogn) O(nlogn) | O ( 1 ) O(1) O(1) | 内部排序 | 不稳定 |
计数排序 | O ( n + r ) O(n+r) O(n+r) | O ( n + r ) O(n+r) O(n+r) | O ( n + r ) O(n+r) O(n+r) | O ( r ) O(r) O(r) | 外部排序 | 稳定 |
桶排序 | O ( n + k ) O(n+k) O(n+k) | O ( n 2 ) O(n^2) O(n2) | O ( n + k ) O(n+k) O(n+k) | O ( n + k ) O(n+k) O(n+k) | 外部排序 | 稳定 |
基数排序 | O ( n ∗ k ) O(n*k) O(n∗k) | O ( n ∗ k ) O(n*k) O(n∗k) | O ( n ∗ k ) O(n*k) O(n∗k) | O ( n + k ) O(n+k) O(n+k) | 外部排序 | 稳定 |
其中,n表示数据规模,即待排序的数据规模;桶排序的k表示“桶” 的个数;计数排序的r表示数据范围;基数排序的d表示最大位数、r表示数据范围。
一、冒泡排序(BubbleSort)
1.算法简介
冒泡排序(Bubble Sort)是一种简单的排序算法,它会重复地比较相邻的两个元素,如果它们的顺序错误就交换它们。通过多次的比较和交换,最大(或最小)的元素会逐渐“浮”到数组的一端,向水下的鱼再向上冒泡一样,因此得名“冒泡”。
2.算法步骤
- 1.比较相邻的元素,如果第一个比第二个大,就交换他们两个;
- 2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数;
- 3.针对所有的元素重复以上的步骤,除了最后一个;
- 4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较;
3.算法特征
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( 1 ) O(1) O(1)
- 稳定性:稳定
4.算法实现
public class BubbleSortAlgorithm {
public void bubbleSort(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j+1 < arrays.length-i; j++) {
if (arrays[j] > arrays[j+1]) {
int temp = arrays[j+1];
arrays[j+1] = arrays[j];
arrays[j] = temp;
}
}
System.out.println("第"+(i+1)+"趟之后:"+Arrays.toString(arrays));
}
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,-62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
new BubbleSortAlgorithm().bubbleSort(arrays);
System.out.println("冒泡排序后:"+Arrays.toString(arrays));
}
}
二、选择排序(SelectionSort)
1.算法简介
选择排序(Selection Sort)是一种简单直观的排序算法,它的基本思想是每次从待排序的数据中选择最小(或最大)的元素,放到已排序部分的末尾,直到所有元素都排序完成。
2.算法步骤
- 1.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
- 2.再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
- 3.重复第二步,直到所有元素均排序完毕。
3.算法特征
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( 1 ) O(1) O(1)
- 稳定性:不稳定
4.算法实现
public class SelectionSortAlgorithm {
// 选择排序法
public static void selectionSort(int arrays[]) {
// 总共要经过 N-1 轮比较
for (int i = 0; i < arrays.length-1; i++) {
int min = i;
// 每轮需要比较的次数 N-i
for (int j = i + 1; j < arrays.length; j++) {
if (arrays[j] < arrays[min]) {
// 记录目前能找到的最小值元素的下标
min = j;
}
}
// 将找到的最小值和i位置所在的值进行交换
if (i != min) {
int temp = arrays[i];
arrays[i] = arrays[min];
arrays[min] = temp;
}
}
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,-62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
selectionSort(arrays);
System.out.println("选择排序后:"+Arrays.toString(arrays));
}
}
三、插入排序(InsertionSort)
1.算法简介
插入排序(Insertion Sort)是一种简单直观的排序算法,它的工作过程类似于整理扑克牌。插入排序的基本思想是将未排序的元素逐个插入到已排序的部分,构建一个有序序列。
2.算法步骤
- 1.从第一个元素开始,该元素可以认为已经被排序
- 2.取出下一个元素,在已经排序的元素序列中从后向前扫描(从第2个元素开始和前面已经排序好的比较)
- 3.如果该元素(已排序)大于新元素,将该元素移到下一位置
- 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 5.将新元素插入到该位置后
- 6.重复步骤2~5
3.算法特征
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( 1 ) O(1) O(1)
- 稳定性:稳定
4.算法实现
public class InsertionSortAlgorithm {
public void insertionSort(int arrays[]) {
// 从第二个元素开始,和前面的有序表进行比较
int j;
for (int i = 1; i < arrays.length; i++) {
int insertVal = arrays[i]; // 记录要插入的值,并保存在temp中,防止数据移动时该元素丢失
for (j = i; j > 0 && arrays[j-1] > insertVal; j--) {
arrays[j] = arrays[j-1];
}
arrays[j] = insertVal;
// System.out.println("第"+i+"趟之后:"+Arrays.toString(arrays));
}
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,-62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
new InsertionSortAlgorithm().insertionSort(arrays);
System.out.println("插入排序后:"+Arrays.toString(arrays));
}
}
四、希尔排序(ShellSort)
1.算法简介
希尔排序(Shell Sort)是一种改进的插入排序算法,也称为“缩小增量排序”。希尔排序通过引入一个增量序列来改进插入排序的性能,减少了数据移动的次数,从而提高了排序的效率。
2.算法步骤
- 1.确定一个元素间隔数step。
- 2.将参加排序的序列按此间隔数从第1个元素开始依次分成若干个子序列。
- 3.在各个子序列中采用某种排序算法(例如插入排序算法)进行排序。
- 4.减少间隔数,重复2-4步,直到间隔数step= 1。
3.算法特征
希尔排序的时间复杂度计算方式比较复杂。
- 时间复杂度: O ( n ∗ l o g n ) O(n*logn) O(n∗logn)
- 空间复杂度: O ( 1 ) O(1) O(1)
- 稳定性:不稳定
4.算法实现
public class ShellSortAlgorithm {
public void shellSort(int arrays[]) {
int length = arrays.length;
int temp;
for (int step = length / 2; step >= 1; step /= 2) {
for (int i = step; i < length; i++) {
temp = arrays[i];
int j = i - step;
while (j >= 0 && arrays[j] > temp) {
arrays[j + step] = arrays[j];
j -= step;
}
arrays[j + step] = temp;
}
}
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,-62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
new ShellSortAlgorithm().shellSort(arrays);
System.out.println("归并排序后:"+Arrays.toString(arrays));
}
}
五、归并排序(MergeSort)
1.算法简介
归并排序(Merge Sort)是一种基于分治思想的经典排序算法,它将一个未排序的数组递归地分成两个子序列,对这两个子序列分别进行排序,然后将这两个有序子序列合并为一个有序序列。
2.算法步骤
- 1.从第一个元素开始,该元素可以认为已经被排序
- 2.取出下一个元素,在已经排序的元素序列中从后向前扫描(从第2个元素开始和前面已经排序好的比较)
- 3.如果该元素(已排序)大于新元素,将该元素移到下一位置
- 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 5.将新元素插入到该位置后
- 6.重复步骤2~5
3.算法特征
- 时间复杂度: O ( n ∗ l o g n ) O(n*logn) O(n∗logn)
- 空间复杂度: O ( n ) O(n) O(n)
- 稳定性:稳定
4.算法实现
public class MergeSortAlgorithm {
public void mergeSort(int[] array) {
if(array == null || array.length <= 1) {
return;
}
int[] newArray = new int[array.length];
sort(array, 0, array.length-1, newArray);
}
// 排序
public void sort(int arrays[], int left, int right, int[] newArray) {
if(left >= right) {
return;
}
int mid = left + (right - left)/2;;
sort(arrays, left, mid, newArray);
sort(arrays, mid + 1, right, newArray);
for(int i = left; i <= right; i++) {
newArray[i] = arrays[i];
}
// 归并
int i = left;
int j = mid + 1;
int k = left;
while(i <= mid && j <= right) {
if(newArray[i] <= newArray[j]) { // 等号会影响算法的稳定性
arrays[k++] = newArray[i++];
} else {
arrays[k++] = newArray[j++];
}
}
if(i <= mid) {
arrays[k++] = newArray[i++];
}
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,-62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
new MergeSortAlgorithm().mergeSort(arrays);
System.out.println("归并排序后:"+Arrays.toString(arrays));
}
}
六、快速排序(QuickSort)
1.算法简介
快速排序(Quick Sort)是一种常用的基于分治思想的排序算法,其核心思想是选择一个基准值,将数组分割为两部分,一部分的元素都小于基准值,另一部分的元素都大于基准值,然后对这两部分分别进行递归排序。
2.算法步骤
- 1.从数列中挑出一个元素,称为“基准”
- 2.重新排序数列,所有比基准值小的元素摆在基准的前面,所有比基准大的元素摆在基准的后面。
- 3.递归地把小于基准值元素的子数列和大于基准值元素的子数列排序
3.算法特征
- 时间复杂度: O ( n ∗ l o g n ) O(n*logn) O(n∗logn)
- 空间复杂度: O ( l o g n ) O(logn) O(logn)
- 稳定性:不稳定
4.算法实现
public class QuickSortAlgorithm {
//快速排序法
public void quickSort(int arrays[], int left, int right) {
if (right < left) { //元素个数小于一个
return;
}
int pivotKey = arrays[left];
int l = left; //左边界
int r = right; //右边界
while (l < r) {
//右边的值大于基数时,右指针左移1位。即找出右边小于基数的值
while (l < r && arrays[r] >= pivotKey) {
r--;
}
if (l < r) {
arrays[l] = arrays[r]; //将右指针对应小于基数的值放到左指针所指的位置
l++; //左指针被赋值为右边小于基数的值后,自增
}
//左边的值小于基数时,左指针右移1位。即找出左边大于基数的值
while (l < r && arrays[l] <= pivotKey) {
l++;
}
if (l < r) { //相反,找到大于基数的下标
arrays[r] = arrays[l];
r--;
}
}
arrays[l] = pivotKey;
//处理当前数组的左半部分,不包括下标为pivot的元素
quickSort(arrays, left, r-1);
//处理当前数组的右半部分,不包括下标为pivot的元素
quickSort(arrays, l+1, right);
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,-62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
new QuickSortAlgorithm().quickSort(arrays, 0, arrays.length-1);
System.out.println("快速排序后:"+Arrays.toString(arrays));
}
}
七、堆排序(HeapSort)
1.算法简介
堆排序(Heap Sort)是一种基于堆数据结构实现的排序算法,它利用最大堆(Max Heap)或最小堆(Min Heap)来实现排序过程。
堆是一种完全二叉树,其中每个父节点的值大于等于(最大堆)或小于等于(最小堆)其子节点的值。堆排序的基本思想是通过构建一个二叉堆,然后依次将堆顶元素(最大值或最小值)与堆底元素交换,调整堆使得剩余元素继续保持堆的性质,重复这个过程直到所有元素有序。
2.算法步骤
- 1.构建一个堆Heap[0, … , … ,n-1];
- 2.把堆首(最大值)和堆尾互换;
- 3.把堆的尺寸缩小1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
- 4.重复步骤 2,直到堆的尺寸为 1。
3.算法特征
- 时间复杂度: O ( n ∗ l o g n ) O(n*logn) O(n∗logn)
- 空间复杂度: O ( 1 ) O(1) O(1)
- 稳定性:不稳定
4.算法实现
public class HeapSortAlgorithm {
/**
* 堆排序的主要入口方法,共两步。
*/
public void heapSort(int[] arrays) {
/*
* 第一步:将数组堆化
* beginIndex = 第一个非叶子节点。
* 从第一个非叶子节点开始即可。无需从最后一个叶子节点开始。
* 叶子节点可以看作已符合堆要求的节点,根节点就是它自己且自己以下值为最大。
*/
int len = arrays.length - 1;
int beginIndex = (arrays.length >> 1)- 1;
for (int i = beginIndex; i >= 0; i--) {
maxHeapify(i, len, arrays);
}
/*
* 第二步:对堆化数据排序
* 每次都是移出最顶层的根节点A[0],与最尾部节点位置调换,同时遍历长度 - 1。
* 然后从新整理被换到根节点的末尾元素,使其符合堆的特性。
* 直至未排序的堆长度为 0。
*/
for (int i = len; i > 0; i--) {
swap(0, i, arrays);
maxHeapify(0, i - 1, arrays);
}
}
private void swap(int i, int j, int arrays[]) {
int temp = arrays[i];
arrays[i] = arrays[j];
arrays[j] = temp;
}
/**
* 调整索引为 index 处的数据,使其符合堆的特性。
*
* @param index 需要堆化处理的数据的索引
* @param len 未排序的堆(数组)的长度
*/
private void maxHeapify(int index, int len, int[] arrays) {
int li = (index << 1) + 1; // 左子节点索引
int ri = li + 1; // 右子节点索引
int cMax = li; // 子节点值最大索引,默认左子节点。
if (li > len) return; // 左子节点索引超出计算范围,直接返回。
if (ri <= len && arrays[ri] > arrays[li]) // 先判断左右子节点,哪个较大。
cMax = ri;
if (arrays[cMax] > arrays[index]) {
swap(cMax, index, arrays); // 如果父节点被子节点调换,
maxHeapify(cMax, len, arrays); // 则需要继续判断换下后的父节点是否符合堆的特性。
}
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,-62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
new HeapSortAlgorithm().heapSort(arrays);
System.out.println(" 堆排序后:"+Arrays.toString(arrays));
}
}
八、基数排序(Radix Sort)
1.算法简介
基数排序(Radix Sort)是一种非比较性的排序算法,它通过对整数按照位数进行分配和收集来实现排序。基数排序将整数视为d位数字序列,从低位到高位依次进行排序,最终得到有序的整数序列。
2.算法步骤
- 1.将整数按位数切割成不同的数字
- 2.然后按每个位数分别比较。
3.算法特征
基数排序的时间复杂度取决于待排序数据的最大位数d、数据范围r和数据个数n。
- 时间复杂度: O ( d + ( n + r ) ) O(d+(n+r)) O(d+(n+r))
- 空间复杂度: O ( n + r ) O(n+r) O(n+r)
- 稳定性:稳定
4.算法实现
public class RadixSortAlgorithm {
//基数排序法
public static void radixSort(int arrays[]) {
int maxValue = Arrays.stream(arrays).max().getAsInt(); // 找出数组arrays中的最大值
int exp = 1; // 指数
int[] buf = new int[arrays.length]; // 存储"被排序数据"的临时数组
// 从个位开始,对数组a按"指数"进行排序
while (maxValue >= exp) {
int[] buckets = new int[10]; // 将数字出现的次数存储在buckets[]中
for (int i = 0; i < arrays.length; i++) {
int digit = (arrays[i] / exp) % 10;
buckets[digit]++;
}
for (int i = 1; i < 10; i++) {
buckets[i] += buckets[i - 1];
}
for (int i = arrays.length - 1; i >= 0; i--) {
int digit = (arrays[i] / exp) % 10;
buf[buckets[digit] - 1] = arrays[i];
buckets[digit]--;
}
// 将排序好的数据赋值给a[]
for (int i = 0; i < arrays.length; i++) {
arrays[i] = buf[i];
}
exp *= 10;
}
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
radixSort(arrays);
System.out.println("基数排序后:"+Arrays.toString(arrays));
}
}
九、计数排序(CountingSort)
1.算法简介
计数排序(Counting Sort)是一种非比较性的稳定排序算法,适用于对一定范围内的整数进行排序。计数排序的核心思想是统计每个元素出现的次数,然后根据元素的大小顺序输出排序后的结果。
计数排序存在两大局限性:
- 数组中最大和最小的元素差距不能过大,因为会占用大量空间;
- 当数组中的元素必须是非负整数,否则无法申请计数数组。
2.算法步骤
- 找出待排序的数组中最大和最小的元素,根据最大和最小元素的差值范围,申请额外计数数组。
- 统计数组中每个元素的出现次数,并将统计结果存储在额外的计数数组中。
- 根据计数数组中的值(即每个元素出现的次数),将对应的元素按顺序放入新的数组中,使得新数组中的元素有序。
3.算法特征
计数排序的时间复杂度取决于数据范围r(最大值与最小值之差加一)和数据个数n。
- 时间复杂度: O ( n + r ) O(n+r) O(n+r)
- 空间复杂度: O ( r ) O(r) O(r)
- 稳定性:稳定
4.算法实现
public class CountingSortAlgorithm {
public void countingSort(int[] arrays, int maxValue) {
int bucketLen = maxValue + 1;
int[] bucket = new int[bucketLen];
for (int value : arrays) {
bucket[value]++;
}
int sortedIndex = 0;
for (int j = 0; j < bucketLen; j++) {
while (bucket[j] > 0) {
arrays[sortedIndex++] = j;
bucket[j]--;
}
}
}
private int getMaxValue(int[] arrays) {
int maxValue = arrays[0];
for (int value : arrays) {
if (maxValue < value) {
maxValue = value;
}
}
return maxValue;
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
int maxValue = new CountingSortAlgorithm().getMaxValue(arrays);
new CountingSortAlgorithm().countingSort(arrays, maxValue);
System.out.println("计数排序后:"+Arrays.toString(arrays));
}
}
十、桶排序(BucketSort)
1.算法简介
桶排序(Bucket Sort)又称箱排序,是计数排序的升级版。其算法原理是将元素分到有限数量的桶里,对每个桶中的元素进行排序,然后按顺序将各个桶的元素合并,得到最终有序的结果。
它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。是一种用空间换取时间的排序。
为了使桶排序更高效,应注意以下两点:
- 在额外空间充足的情况下,尽量增大桶的数量
- 使用的映射函数能够将输入的 n 个数据均匀的分配到 k 个桶中
2.算法步骤
- 寻找数组中最大元素和最小元素并计算桶的大小bucketSize和个数bucketCount;
- 将元素均匀地分散到多个桶中;
- 对每个桶中的元素进行排序(通常使用的是插入排序等简单排序算法);
- 合并各个桶中的元素,得到有序序列。
3.算法特征
桶排序的时间复杂度取决于桶的个数k和数据规模n。
- 时间复杂度: O ( n + k ) O(n+k) O(n+k)
- 空间复杂度: O ( n + k ) O(n+k) O(n+k)
- 稳定性:稳定
4.算法实现
public class BucketSortAlgorithm {
public void bucketSort(int[] arrays) {
if (arrays.length == 0) {
return;
}
// 寻找最大和最小元素
int minValue = arrays[0];
int maxValue = arrays[0];
for (int value : arrays) {
if (value < minValue) {
minValue = value;
} else if (value > maxValue) {
maxValue = value;
}
}
int bucketSize = (maxValue - minValue) / arrays.length + 1; // 计数桶存储数的范围大小
int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1; // 计数桶的个数,
int[][] buckets = new int[bucketCount][0];
// 利用映射函数将数据分配到各个桶中
for (int i = 0; i < arrays.length; i++) {
int index = (int) Math.floor((arrays[i] - minValue) / bucketSize);
buckets[index] = arraysAppend(buckets[index], arrays[i]);
}
int arraysIndex = 0;
for (int[] bucket : buckets) {
if (bucket.length <= 0) {
continue;
}
// 对每个桶进行排序,这里使用了库函数的快速排序
Arrays.sort(bucket);
for (int value : bucket) {
arrays[arraysIndex++] = value;
}
}
}
// 自动扩容
private int[] arraysAppend(int[] arr, int value) {
arr = Arrays.copyOf(arr, arr.length + 1);
arr[arr.length - 1] = value;
return arr;
}
public static void main(String[] args) {
int arrays[] = {6,2,13,27,49,74,12,64,5,4,-62,99,5,17,18,23,34,15,35,25,53,51};
System.out.println("原始数据集:"+Arrays.toString(arrays));
new BucketSortAlgorithm().bucketSort(arrays);
System.out.println(" 桶排序后:"+Arrays.toString(arrays));
}
}