1.希尔排序
思想:希尔排序可以看成是对直接插入排序的一种改进,它不再是相邻的比较,而是隔着一定的增量。隔着一定的距离的数为一组,同组内进行比较排序(使用直接插入排序),每一组都比较好了,即为一轮,然后增量减小,继续进行下一轮,当减小到一,则排序结束。(图片选自网络)
我们可以根据至上而下 自下而上的思想,先实现同组内的比较交换这个小模块,再用这个模块进一步实现增量减小。同组内交换为直接插入排序
private static void ShellInsert(int[] a,int incre) {
int j=0;
for(int i=1+incre;i<a.length;i++){
//第一组内的第二个数为1+incre,故从此开始,循环体执行一次表示a[i]与a[i-incre]、a[i-2incre]......以此类推,排好序了
//i++则是到下一组去,或是恰好从最后一组+1出去了,又回到第一组,即i+incre,再循环一次,与同组的前几个数排好序
if(a[i]<a[i-incre]){
a[0]=a[i];
j=i-incre;
while((j>0)&&(a[0]<a[j]))
{
a[j+incre]=a[j];
j=j-incre;
}
j=j+incre;
a[j]=a[0];
}
}
}
实现增量减小调用ShellInsert,即希尔排序算法,完整代码如下:
public class ShellSortDemo {
public static void main(String[] args) {
int a[]={0,46,55,13,42,44,17,05,70};
ShellSort(a);
for(int i=1;i<a.length;i++)
System.out.print(a[i]+",");
}
private static void ShellSort(int a[]) {
int incre=a.length;
do{
incre=incre/2;
ShellInsert(a,incre);
}while(incre!=1);
}
private static void ShellInsert(int[] a,int incre) {
int j=0;
for(int i=1+incre;i<a.length;i++){
//第一组内的第二个数为1+incre,循环体执行一次表示a[i]与a[i-incre]、a[i-2incre]......以此类推,排好序了
//i++则到下一组去,或是恰好从最后一组+1出去了,又回到第一组,即i+incre,再循环一次,与同组的前几个数排好序
if(a[i]<a[i-incre]){
a[0]=a[i];
j=i-incre;
while((j>0)&&(a[0]<a[j]))//j大于0才有意义,此时a[0]不是哨兵
{
a[j+incre]=a[j];
j=j-incre;
}
j=j+incre;
a[j]=a[0];
}
}
}
}