4.希尔排序
插入排序存在的问题:
2,3,4,5,6,7,1
希尔排序针对插入排序存在的问题,做出了改进
4.1排序思路
4.1具体实现
1.交换法
1.第一轮排序
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void shellSort(int[] array) {
//第一轮排序
//将10个数据分成了5组10/2=5
int temp = 0;
for (int i = 5; i < array.length; i++) {
//从第一元素开始配对做比较
for (int j = i - 5; j >= 0; j -= 5) {
if (array[j] > array[j + 5]) {
temp = array[j];
array[j] = array[j + 5];
array[j + 5] = temp;
}
}
}
}
}
[3, 5, 1, 6, 0, 8, 9, 4, 7, 2]
2.第二轮排序
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void shellSort(int[] array) {
//第一轮排序
//将10个数据分成了5组 10/2=5
int temp = 0;
for (int i = 5; i < array.length; i++) {
//从第一元素开始配对做比较
for (int j = i - 5; j >= 0; j -= 5) {
if (array[j] > array[j + 5]) {
temp = array[j];
array[j] = array[j + 5];
array[j + 5] = temp;
}
}
}
//第二轮排序
//将10个数组分成了2组 10/2=5/2=2
for (int i = 2; i < array.length; i++) {
//从第一元素开始配对做比较
for (int j = i - 2; j >= 0; j -= 2) {
if (array[j] > array[j + 2]) {
temp = array[j];
array[j] = array[j + 2];
array[j + 2] = temp;
}
}
}
}
}
[0, 2, 1, 4, 3, 5, 7, 6, 9, 8]
3.第三轮排序
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void shellSort(int[] array) {
//第一轮排序
//将10个数据分成了5组 10/2=5
int temp = 0;
for (int i = 5; i < array.length; i++) {
//从第一元素开始配对做比较
for (int j = i - 5; j >= 0; j -= 5) {
if (array[j] > array[j + 5]) {
temp = array[j];
array[j] = array[j + 5];
array[j + 5] = temp;
}
}
}
//第二轮排序
//将10个数组分成了2组 10/2=5/2=2
for (int i = 2; i < array.length; i++) {
//从第一元素开始配对做比较
for (int j = i - 2; j >= 0; j -= 2) {
if (array[j] > array[j + 2]) {
temp = array[j];
array[j] = array[j + 2];
array[j + 2] = temp;
}
}
}
//第三轮排序
//将10个数组分成了1组 10/2=5/2=2/2=1
//使用插入排序
for (int i = 1; i < array.length; i++) {
//从第一元素开始配对做比较
for (int j = i - 1; j >= 0; j -= 1) {
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4.代码优化
public class ShellSort1 {
public static void main(String[] args) {
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void shellSort(int[] array) {
int temp = 0;
for (int gap = array.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < array.length; i++) {
//从第一元素开始配对做比较
for (int j = i - gap; j >= 0; j -= gap) {
if (array[j] > array[j + gap]) {
temp = array[j];
array[j] = array[j + gap];
array[j + gap] = temp;
}
}
}
}
}
}
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2.移位法
public class ShellSort2 {
public static void main(String[] args) {
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void shellSort(int[] array) {
//分组
for (int gap = array.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < array.length; i++) {
int insertIndex = i;
int insertVal = array[insertIndex];
//比较配对的两个数的大小
while (insertIndex -gap>= 0 && insertVal<array[insertIndex-gap]){
array[insertIndex]=array[insertIndex-gap];
insertIndex-=gap;
}
array[insertIndex]=insertVal;
}
}
}
}
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4.2测试希尔排序算法速度
1.交换法
public class ShellSort1 {
public static void main(String[] args) {
// int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
// shellSort(arr);
// System.out.println(Arrays.toString(arr));
int[] arr=new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i]=(int)(Math.random()*800000);
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format1 = simpleDateFormat1.format(date1);
System.out.println("排序前的时间是:"+format1);
shellSort(arr);
Date date2 = new Date();
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format2 = simpleDateFormat2.format(date2);
System.out.println("排序后的时间是:"+format2);
}
public static void shellSort(int[] array) {
int temp = 0;
for (int gap = array.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < array.length; i++) {
//从第一元素开始配对做比较
for (int j = i - gap; j >= 0; j -= gap) {
if (array[j] > array[j + gap]) {
temp = array[j];
array[j] = array[j + gap];
array[j + gap] = temp;
}
}
}
}
}
}
排序前的时间是:2021-01-09 13:38:40
排序后的时间是:2021-01-09 13:38:51
速度反而比插入排序慢,没有必要
2.移位法
public class ShellSort2 {
public static void main(String[] args) {
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i] = (int) (Math.random() * 800000);
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format1 = simpleDateFormat1.format(date1);
System.out.println("排序前的时间是:" + format1);
shellSort(arr);
Date date2 = new Date();
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format2 = simpleDateFormat2.format(date2);
System.out.println("排序后的时间是:" + format2);
}
public static void shellSort(int[] array) {
//分组
for (int gap = array.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < array.length; i++) {
int insertIndex = i;
int insertVal = array[insertIndex];
//比较配对的两个数的大小
while (insertIndex -gap>= 0 && insertVal<array[insertIndex-gap]){
array[insertIndex]=array[insertIndex-gap];
insertIndex-=gap;
}
array[insertIndex]=insertVal;
}
}
}
}
排序前的时间是:2021-01-09 14:06:10
排序后的时间是:2021-01-09 14:06:10