希尔排序

1:希尔排序原理分析

希尔排序解决的问题是:针对{8,7,9,4,5,0,2,6,3,1}进行插入排序时,由于较小的数在序列的后面,所以在插入排序时,会出现多次移动覆盖的情况,这正是由于较小数在后面造成的。所以我们要一定的优化处理,可以有效避免这种情况的发生!希尔排序d额操作如下图所示;

 

 假设有10个数据

进行第一轮的排序操作如下:以array.length/2为gap,进行以gap为5分成5组,每组2个数据,然后对每组数据进行插入排序。

进行第二轮的排序操作如下:以array.length/2/2为gap,进行以gap为2分成2组,每组5个数据,然后对每组数据进行插入排序。

进行第三轮的排序操作如下:以array.length/2/2/2为gap,进行以gap为1分成1组,每组10个数据,然后对每组数据进行插入排序。

2:代码实现

package sort;

import java.util.Arrays;

public class ShellSortTest {
    int[] array = new int[] {8,7,9,4,5,0,2,1,3,6};

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ShellSortTest sst = new ShellSortTest();
        sst.ShellSort();
    }

    
    public void ShellSort() {
        
        System.out.println("原始数据:"+Arrays.toString(array));
//        
//        //第一轮写入希尔排序,将数据分为array.length/2 =5组,每组为2个数据。
//        int gap = 5;//以5为gap,分成5组,每组两个元素的序列
//        for(int i =0;i<5;i++) {
//            for(int j=9-i;j>=5;j=j-5) {//从后到前
//                int temp = array[j];//保存分组数据的后一位
//                if(j>1&&array[j]<array[j-5]) {
//                    array[j] = array[j-5];
//                    array[j-5] = temp;
//                }
//            }
//        }
//        
//        System.out.println("第一轮分5组的结果:"+Arrays.toString(array));
//        
//        
//        //第二轮写入希尔排序,将数据分为array.length/2/2 =2组,每组为5个数据。
//        gap = 2;//以2为gap,分成2组,每组5个元素的序列
//        for(int i =0;i<2;i++) {//两组数据,两轮循环
//            for(int j=9-i;j>=0;j=j-2) {//从后到前
//                int temp = array[j];//保存分组数据的后一位
//                if(j>1&&array[j]<array[j-2]) {
//                    array[j] = array[j-2];
//                    array[j-2] = temp;
//                }
//            }
//        }
//        
//        System.out.println("第2轮分2组的结果:"+Arrays.toString(array));
//        
//        
//        
//        //第三轮写入希尔排序,将数据分为array.length/2/2/2 =1组,每组为10个数据。
//        gap = 1;//以1为gap,分成1组,每组10个元素的序列
//        for(int i =0;i<1;i++) {//一组数据,一轮循环
//            for(int j=9-i;j>=0;j=j-1) {//从后到前
//                int temp = array[j];//保存分组数据的后一位
//                if(j>0&&array[j]<array[j-1]) {
//                    array[j] = array[j-1];
//                    array[j-1] = temp;
//                }
//            }
//        }
//        
//        System.out.println("第3轮分1组的结果:"+Arrays.toString(array));
    
        
        
        //从特殊到一般
        int gap = array.length/2;//
        while(true) {//根据gap的值来进行分组循环,每次gap/2,
            for(int i =0;i<gap;i++) {//分出几组的数据,循环几次
                for(int j=9-i;j>=0;j=j-gap) {//对每组数据进行插入排序的内部循环
                    int temp = array[j];//保存分组数据的后一位
                    if((j-gap>=0)&&(array[j]<array[j-gap])) {
                        array[j] = array[j-gap];
                        array[j-gap] = temp;
                    }
                }
            }
            if(gap == 1)
                break;
            gap = gap/2;//gap不等于1,则意味着还要继续分组
        }
        
        System.out.println("结果:"+Arrays.toString(array));
        
    }
}

从特殊到一般的方式来退出希尔排序的算法!!

posted @ 2020-02-25 11:13  大朱123  阅读(201)  评论(0编辑  收藏  举报