什么是希尔排序
希尔排序是插入排序的优化,引入了步长的概念
引入步长的概念 元素个数/2=8/2=4
分组之间进行插入排序
分组一 5 5
分组二 3 9
分组三 2 1
分组四 8 0
进行插入排序 然后变为 5 3 1 0 5 9 2 8 步长变为4/2=2
分组一 5 1 5 2
分组二 3 0 9 8
进行插入排序 变为 1 0 2 3 5 8 5 9 步长变为 2/2=1
分组一 1 0 2 3 5 8 5 9
进行插入排序 变为0 1 2 3 5 5 8 9
希尔排序的时间以及空间复杂度
平均时间复杂度为O(n * log(n))
空间复杂度为O(1)
是不稳定的排序算法
工具类的修改
public static void shellSort(int[] arr) {
int length = arr.length;
int step = length / 2;
int i,j;
int orgin;
int index;
while(step >= 1)
{
//步长大于等于1进入循环
for(i = 0; i < length;i++)
{
for(j = i + step ;j < length;j += step)
{
orgin = arr[j];
index = j - step;
while(index >= 0 && orgin < arr[index])
{
arr[index + step] = arr[index];
index -= step;
}
if(index < 0) arr[i] = orgin;
else arr[index + step] = orgin;
}
}
step /= 2;
}
}
插入排序
我的另一篇博客:点我
与插入排序的比较
public static void insertSort(int[] arr)
{
int i = 0;
int orign;
int index;
int length = arr.length;
for(i = 1; i < length;i++)
{
orign = arr[i];
index = i-1;//1
while(index >= 0 && arr[index] > orign)
{
arr[index+1] = arr[index];
index--;
}
if(index < 0) arr[0] = orign;
else arr[index+1] = orign;
}
}
主要的逻辑不同之处在
对于希尔排序 我们进行比较时候当前元素的下一个元素应该是 当前元素+步长,增长的幅度也应该是+步长,那么对于外层for循环就应该修改为
for(j = 前一个元素+步长; j < length;j += 步长)
{
}
//对应希尔排序中的
for(j = i + step ;j < length;j += step)
{
}
对于里面的修改只要是+1,都应该修改为+步长,因为是以步长进行分组的,每组内部进行插入,与此同时对于arr[0]来说,对于插入排序就是组内的第一个元素,那么对于希尔排序组内的第一个元素就是arr[i]
orign = arr[i];
index = i-步长;//1
while(index >= 0 && arr[index] > orign)
{
arr[index + 步长] = arr[index];
index -= 步长;
}
if(index < 0) arr[组内第一个元素的下标] = orign;
else arr[index + 步长] = orign;
//对应希尔排序中的
orgin = arr[j];
index = j - step;
while(index >= 0 && orgin < arr[index])
{
arr[index + step] = arr[index];
index -= step;
}
if(index < 0) arr[i] = orgin;
else arr[index + step] = orgin;
工具类的使用
public class Test {
public static void main(String[] args) {
int[] arr = new int[] {8,3,2,1,7};
SortUtil.shellSort(arr);
StringBuilder sBuilder = new StringBuilder();
sBuilder.append("[");
for (int i : arr) {
sBuilder.append(i);
sBuilder.append(",");
}
sBuilder.reverse();
sBuilder.deleteCharAt(0);
sBuilder.reverse();
sBuilder.append("]");
System.out.println(sBuilder);
}
}