本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1.希尔排序
希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。
一般的初次取序列的一半为增量,以后每次减半,直到增量为1。
给定实例的shell排序的排序过程
假设待排序文件有10个记录,其关键字分别是:
49,38,65,97,76,13,27,49,55,04。 增量序列的取值依次为:5,2,1
package test1;
import java.util.Arrays;
/**
* @author 小徐同学
*
* 2021年10月30日
*/
public class ShellSort {
public static void main(String[] args){
int[] array={49,38,65,97,76,13,27,49,78,34,12,64,1};
System.out.println("排序前"+Arrays.toString(array));
//希尔排序
int gap = array.length;
while (true) {
gap /= 2; //增量每次减半
for (int i = 0; i < gap; i++) {
for (int j = i + gap; j < array.length; j += gap) {//这个循环里其实就是一个插入排序
int k = j - gap;
while (k >= 0 && array[k] > array[k+gap]) {
int temp = array[k];
array[k] = array[k+gap];
array[k + gap] = temp;
k -= gap;
}
}
}
if (gap == 1)
break;
}
System.out.println();
System.out.println("排序后"+Arrays.toString(array));
}
}
结果
排序前[49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 1] 排序后[1, 12, 13, 27, 34, 38, 49, 49, 64, 65, 76, 78, 97]
2.归并排序
递归式归并排序
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并
归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作 如 设有数列{6,202,100,301,38,8,1} 初始状态: [6] [202] [100] [301] [38] [8] [1] 比较次数 i=1 [6 202 ] [ 100 301] [ 8 38] [ 1 ] 3 i=2 [ 6 100 202 301 ] [ 1 8 38 ] 4 i=3 [ 1 6 8 38 100 202 301 ] 4 总计: 11次代码
package test1;
import java.util.Arrays;
/**
* @author 小徐同学
*
* 2021年10月30日
*/
public class MergeSort {
//测试
public static void main(String[] args) {
Integer[] I = {5,3,1,4,2,10,6,7};
System.out.println("排序前:"+Arrays.toString(I));
sort(I);
System.out.println("排序后:"+Arrays.toString(I));
}
//实现归并操作
public static void merge(Comparable[] a, int lo, int mid, int hi){
//定义三个指针
int p1= lo; //p1指向左子组的第一个元素
int p2= mid+1; //p2指向右子组的第一个元素
int i = lo; //i指向辅助数组的第一个元素
//定义辅助数组
Comparable[] aux = new Comparable[a.length];
//实现归并
while(p1<=mid || p2<=hi) {
if (p1 > mid) aux[i++] = a[p2++];
else if (p2 > hi) aux[i++] = a[p1++];
else if (a[p1].compareTo(a[p2]) < 0) aux[i++] = a[p1++];
else aux[i++] = a[p2++];
}
//将排序之后的aux数组复制给原来的数组a,这样a中对应的元素便是有序的
for (int k = lo; k <= hi; k++) {
a[k]=aux[k];
}
}
public static void sort(Comparable[] a){
sort(a,0,a.length-1);
}
public static void sort(Comparable[] a, int lo, int hi){
if (hi<=lo) return;
//分成两组
int mid = lo+(hi-lo)/2;
//通过递归进行排序
sort(a,lo,mid);
sort(a,(mid+1),hi);
merge(a,lo,mid,hi);
}
}
结果
排序前:[5, 3, 1, 4, 2, 10, 6, 7] 排序后:[1, 2, 3, 4, 5, 6, 7, 10]