希尔排序:
也是属于插入排序的一种;
所以它同样拥有插入排序的规律:
下面是网上最常见的插入排序的动图,你能看出什么规律来吗?(关于对插入排序的分析,请看我的另一篇《 简单快速掌握——直接插入排序》,就在这篇文章的后面~)
看看你得出的规律是否跟我得出的规律一样?请往下看:
仔细看图,我们可以得出一个规律:
1红色框的元素,是最新的一个数,在这里我们不妨叫它a【i】,(i从0到n-1),并把它放在temp里。
2temp元素每次都与前面的元素a【j】比较,这里我们用j代替(j=i-i)。
3当temp<a【j】时:a【j】就向后移动;由原来下标a【j】变成了a【j+1】。也就是a【j+1】=a【j】。并且一直比较。
4.直到temp>a【j】的时候,这个时候,a【j】不需要向后移动;这时候temp就直接插入到a【j】的后面,也就是a【j+1】。即a【j+1】=temp;
接下来我们一起来写代码吧:
public void cr(int a[],int n){
for(int i=0;i<n;i++){
int j=i-1;
int temp=a[i];//这是我们找出规律1
while(j>=0 && temp<a[j]){//temp不断地一直与前面的数a【j】作比较。这是规律3
a[j+1]=a[j];
j--;
}
a[j+1]=temp;//当temp>a【j】时,就把temp插入到a【j+1】里。这是规律4
}
}
那么希尔排序又是又怎样的规律呢?
下面是网上最常见的希尔排序过程的动图,你能看出什么规律来吗?
仔细看图,我们可以得出一个规律:
1每个数a【i】,(i从0到n-1)都会与前面一定距离(这个距离的值我们暂且用gap表示)的数a【i-gap】做比较,并把它放在temp里。temp=a【i】;(当然i-gap必须>=0,小于0;自然就不比较了;具体可以看我下面的图解)
2temp元素每次都与前面的元素a【j】比较,这里我们用j代替(j=i-gap)。
3当temp<a【j】时:a【j】就向后移动;由原来下标a【j】变成了a【j+gap】。也就是a【j+gap】=a【j】。并且一直比较。
4.直到temp>a【j】的时候,这个时候,a【j】不需要向后移动;这时候temp就直接插入到a【j】的后面,也就是a【j+gap】。即a【j+gap】=temp;
5我们会发现,它的规律与插入排序的区别,就是a【i】与前面的数比较。而这个数,不再是1的距离,而是gap的距离。gap的变化是:第一次:gap=n/2,第二次:gap=gap/2;第三次:gap=gap/2;……;gap不断地变小,直到gap=1;
接下来我们一起来写代码吧:
public void xier(int a[],int n){
int gap=n/2;
for(;gap>0;gap=gap/2){//这是我们发现的规律5.
for(int i=0;i<n;i++){
int temp=a[i];
int j=i-gap;
while((j>=0)&&(temp<=a[j])){//temp不断地一直与前面的数a【j】作比较。这是规律3
a[j+gap]=a[j];
j=j-gap;
}
a[j+gap]=temp;//当temp>a【j】时,就把temp插入到a【j+gap】里。这是规律4
}
}
}
}
这是希尔排序的代码:
这是插入排序的代码:
区别已经很明显了吧。
就是这样,这就是我对希尔排序与插入排序的理解。
谢谢阅读。