插入排序之希尔排序
排序算法分为以下几类:
1、插入排序
2、交换排序
3、选择排序
4、归并排序
5、基数排序
一、基本思想
本文主要讲述希尔排序,是Shell在1959年基于插入排序改进的算法,希尔排序的时间复杂度是第一个低于o(n^2)的算法,算法复杂度为o(nlogn)。
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
选择间隔gap=4作为分组依据,隔四个划分为同一组。
0,4,8,12,
1,5,9,13,
2,6,10,14,
3,7,11,15,
继续下次循环,使得gap=2
0,2,4,6,8,10,12,14
1,3,5,7,9,11,13,15
继续下一次循环gap=1
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
在上面划分的基础上,使用简单插入排序对其进行排序。
二、代码实现
2.1、源代码
package com.bubaiwantong.sort;
public class ShellSort {
/**
* 希尔排序
*
* @param arr
*/
public void sort(int arr[]) {
/*
h = 1;
gap = 3 * h + 1
while(gap<arr.length/3-1){
gap = 3 * h + 1
}
gap如果取1,4,13,40...ShellSort会最快
本程序为了方便起见gap=4。
*/
for (int gap = 4; gap > 0; gap /= 2) {
/*
0,4,8,12,
1,5,9,13,
2,6,10,14,
3,7,11,15,
i从gap开始,如果gap=4,也就是说从4||5||6||7开始,
将前面的0||1||2||3视为有序的,在前面找到一个合适的位置,插入进去。
*/
for (int i = gap; i < arr.length; i++) {
int temp = arr[i];
int j = i - gap;
while (j >= 0 && arr[j] > temp) {
arr[j + gap] = arr[j]; // 数组后移,给temp腾出空间,直到temp大的时候;为后面arr[j + gap] = temp;做准备
j = j - gap;
}
arr[j + gap] = temp; //while循环退出,说明j<0,这时候需要j+gap才能保证数组不越界访问。
}
}
}
public void printArr(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("");
}
public void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = new int[]{9, 8, 7, 6, 5, 4, 3, 2, 1};
ShellSort shellSort = new ShellSort();
shellSort.sort(arr);
shellSort.printArr(arr);
}
}
2.2、运行结果
1 2 3 4 5 6 7 8 9
Process finished with exit code 0