希尔排序
想了解希尔排序之前我们就要大概的了解下直接插入排序
直接插入排序
定义:是一种最简单的排序算法,基本操作是将一个数插入到已经排好序的序列里面。
void insertSorted(SqList &L){
int i,j;
for(i=2;i<L.len;i++){
//哨兵 将需要比较的元素放到下标为0的位置
L[0]=l[i];
for(j=i-1;L[j]>L[0],j--){
//向后移动比
L[j]=L[j-1];
}
L[j+1]=L[0];
}
}
**简单总结:**下直接插入排序就是先将每个数据元素一次遍历,在遍历的同时进行排序,将遍历的元素放到0号位置,依次和已经排序好的数据进行比对大小,选择排放的位置即可。
复杂度分析:最坏时间复杂度 O(n²)
平均时间复杂度 O(n²)
辅助空间: O(1) 利用0单元进行存放插入数据。
希尔排序
**引入:**那什么是希尔排序呢?希尔排序是建立在直接插入排序的基础上,我们俩分析下 直接插入排序的缺点所在,如果一个序列为
[8,9,78,68,6,59,66,58,35,1],那么我们在执行最后一遍插入数据时候哨兵的值为1,那么我们需要遍历前面所有的数据进行比较,这就是问题所在,可以减少在位置后移的次数。而我认为希尔排序的,可以解决这个较坏的情况,简单点说希尔排序就是在一个序列里面分组排序。
我们来简单的看下希尔排序的简单思想:
首先我们需要选择间隔进行排序
如图:我们这边是以5间隔进行分组排序,分成3组,在每一个组的一号位置进行比较排序,这是第一轮产生的结果,这样就形成了每一个组的相对应的位置上的元素已经是有序的。
这个是进行第二轮的排序的结果,每一组的第二个元素进行排序,在三组里面的第二个元素都是升序状态。
往复这样的操作,将每个组的元素进行组外排序。
然后我们在进行3间隔的排序
最后进行1间隔的排序,即直接插入排序完成排序:
代码实现
void shellsorted(SqList &l,int dk){
//dk 为有序增量 也是上面刚刚的5 3 1
for(i=dk+1;i<l.len;i++){
if(l[i]<l[i-dk]){
l[0]=l[i];
for(j=i-dk;j>0 && l[i]<l[i-dk];j=j-dk){
l[j+dk]=l[j];
l[j+dk]=l[0];
}
}
}
}
void startshellsorted(SqList &l,int dk[],int dk_len){
//dk[] 为有序增量数组 dk_len 为数组的长度
for(int i=0;i<dk_len;i++){
shellsorted(SqList &l,int dk[i]);
}
}
总结:
希尔排序的特点:
1.最后一次少量移动。
2.有序增量为递减,最后一次为1。
3.有序增量为互质的。
希尔算法的排序的时间效率是和增量序列有关的,这个增量的取值涉及到一些数学上尚未解决的难题,
目前尚未有人求得一种最好的增量序列。
目前尚未有人求得一种最好的增量序列。
目前尚未有人求得一种最好的增量序列。
这个是重点,哈哈哈哈哈只要你研究出来了,也许你就不会埋没在历史的长河里啦