希尔排序又称缩小增量排序,是对插入排序的改进版,思想如下:
(1) 根据数组的长度设置适合的增量dk=a.length/3 +1 ,然后将间隔增量的元素与之前的元素组合成一个序列,我在这里简称增量序列。
(2) 对增量元素的序列进行插入排序。
(3) 每趟排序完毕后,将增量缩小为 dk=dk/3+1, 当最后一次增量为1时,排序完毕。
完整代码:
package sort; import java.util.Arrays; /** * @author bingbing * @date 2021/5/21 0021 22:23 * 希尔排序算法实现 */ public class HillSort { public static void main(String[] args) { int[] a = new int[]{5, 1, 3, 2, 4, 6}; int[] result = shellSort(a); System.out.println("最终排序结果为:" + Arrays.toString(result)); } public static int[] shellSort(int[] arr) { int dk = arr.length / 3 + 1; while (dk > 0) { System.out.println("dk:" + dk); insertShellSort(arr, dk); if (dk == 1) { break; } System.out.println("arr:" + Arrays.toString(arr)); dk = dk / 3 + 1; } return arr; } public static void insertShellSort(int[] arr, int dk) { for (int i = dk; i < arr.length; i++) { if (arr[i] < arr[i - dk]) { int j; int x = arr[i]; arr[i] = arr[i - dk]; for (j = i - dk; j >= 0 && x < arr[j]; j = j - dk) { // 逐个后移,找到要插入的位置 arr[j + dk] = arr[j]; System.out.println("i=" + i + ",j=" + j + ",j+dk=" + (j + dk) + ",arr=" + Arrays.toString(arr)); } System.out.println("j + dk=" + (j + dk)); arr[j + dk] = x; System.out.println("===" + Arrays.toString(arr)); } } } }
打印结果:
桶排序的原理很简单,将数组中的所有元素,分别对每个桶进行排序,然后将结果汇总即可。
完整代码:
package sort; import cn.hutool.core.collection.CollectionUtil; import java.util.*; /** * @author bingbing * @date 2021/5/22 0022 15:17 */ public class BucketSort { // [3,6,5,9,7,8] public static void main(String[] args) { int[] a = new int[]{3, 10, 50, 999, 7, 8888, 2, 4, 6, 15, 24, 18, 45, 29, 37, 18, 66}; bucketSort(a); } public static void bucketSort(int[] a) { List<Integer> targetLists = new ArrayList<>(); int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for (int i = 0; i < a.length; i++) { max = Math.max(max, a[i]); min = Math.min(min, a[i]); } int bucketNum = (max - min) / a.length + 1; List<List<Integer>> bucketLists = new ArrayList<>(bucketNum); for (int i = 0; i < bucketNum; i++) { bucketLists.add(new ArrayList<>()); } // 将元素分别放入到桶中 for (int i = 0; i < a.length; i++) { // 除以长度就是所在的区间位置, 因为桶的个数是根据数组的长度计算得来的。 int num = (a[i] - min) / a.length; bucketLists.get(num).add(a[i]); } // 对每个桶进行排序 for (int i = 0; i < bucketLists.size(); i++) { if (!CollectionUtil.isEmpty(bucketLists.get(i))) { Collections.sort(bucketLists.get(i)); System.out.println("桶排序后的结果为:" + bucketLists.get(i)); targetLists.addAll(bucketLists.get(i)); } } System.out.println(targetLists); } }
打印结果: