今天我们不刷力扣了,我们来复习(手撕)一下数据结构中的八大排序算法之一,希尔排序
基本概念:
希尔排序又叫缩小增量排序,也是一种插入排序方法(通常快于直接插入法),具体做法简单理解是将整个需要排序的序列划分为 若干子序列 分别进行直接插入排序
代码:
public static void shellSort(int [] arr){
int gap =arr.length;//创建变量,初始化为数组长度
while (gap >1 ){
gap /=2; //取原来的的一半
shell(arr,gap); //调用直接插入排序方法
}
public static void shell(int[] arr,int gap){
for (int i =gap;i<arr.length ; i++ ){
int tmp =arr[i]; //tmp存放i下标的值
int j =i-gap; //j的值为 i-gap
//每次gap位置
for(;j>=0;j -=gap){
//若arr[j]值较大,则将将该值放到下标为j+gap的位置上
if (arr[j] > tmp){
arr[j + gap] =arr[j];
//否则,直接break
}else {
break;
}
}
//此时下标的值为负数,将tmp的值 放入到下标为j+gap的位置
arr[j+ gap] =tmp;
}
}
代码补充说明:
1、前面部分是设置循环 获取每次的gap的值,同时调用对应的排序方法
2、插入排序部分(关键):
首先第一个循环是遍历数组,i 从gap开始,j 从 i - gap开始
接着第二层循环是 j 每次都会减去gap,此时若 j 位置是负数就比较 j 与tmp 的值
核心思路:
1、选取一个整数gap,将所有元素(数字)相差为 gap的划分到同一组,并对 每一组的元素进行直接插入排序然后再选取新的整数(比上一个整数小),重复上述操作。
2、当选取的整数的大小减到1时,相当于整个数组序列被分到同一组,进行一次直接插入排序。
注意:对于整数gap的选定非确定,当最后一个整数必须为1,且每次后一个整数时前一个整数的1/2 或者1/3(建议1/2)。
注意:
我们分割待排序记录的目的是减少待排序记录的个数,并使整个序列向基本有序发展。而如上面这样分完组后,就各自排序的方法达不到我们的要求。因此,我们需要采取跳跃分割的策略:将相距某个“增量”的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后得到的结果是基本有序而不是局部有序。
学习参考: