• 排序---希尔排序Java


    希尔排序

    插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。
    希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
        基本思想
    先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量为1(选择增量d1=len/2,d2=d1/2...最后增量为1),即所有记录放在同一组中进行直接插入排序为止。
     
    功能要求:输入数组;输出每步骤的步长和排序情况;希望能进行排序方向的选择(从大到小或从小到大)
     
    源代码:
    import java.util.Scanner;
    
    public class XierPaixu {
        
        public static void main(String[] args) {
        /**
         * 键盘输入数组
         */
        int[] a = null;
        System.out.println("请输入数组长度:");
        Scanner sc = new Scanner(System.in);
        int len = 0;
        try {
            len = Integer.parseInt(sc.nextLine());
        } catch (Exception e) {
        }
        a = new int[len];
        System.out.println("请输入数组:");
        for(int i=0;i<a.length;i++) {
            a[i]=sc.nextInt();
        }
        System.out.println("原数组为:");
        for(int i=0;i<a.length;i++) {
            System.out.print(a[i]+" ");
        }
        /**
         * 选择升序或降序
         */
        System.out.println(" ");
        System.out.println("升序请按1;降序请按2");
        Scanner s = new Scanner(System.in);
        int b = 0;
        try {
            b = Integer.parseInt(s.nextLine());
        } catch (Exception e) {
        }
        switch (b){
            case 1:
                xierAsc(a);
                break;
            case 2:
                xierDesc(a);
                break;
            case 0:
                System.out.println("请选择1或2!");
                break;
        }
        
        }
        
        public static void xierAsc(int arr[]) {
            /**
             * 希尔排序---升序
             */
            int len= arr.length;
            for(int d=len/2; d>=1; d=d/2){//选择增量d1=len/2,d2=d1/2...最后增量为1
                for(int i=d; i<len; i++){ //从第d+1个元素,逐个对其所在组进行直接插入排序操作
                    for(int j=i-d; j>=0; j=j-d){
                        if(arr[j] > arr[j + d]) {//符合条件交换位置
                            swap(arr,j,j+d);//j+d 代表即将插入的元素所在的角标
                        }                
                    }
                }
                System.out.println("增量为"+d+"时的排序结果:");
                for(int i=0;i<arr.length;i++) {
                    System.out.print(arr[i]+" ");
                }
                System.out.println(" ");
            }
        }
        public static void swap(int[] arr, int a, int b) {  //交换
            int t = arr[a];  
            arr[a] = arr[b];  
            arr[b] = t;  
        }  
        public static void xierDesc(int arr[]) {
            /**
             * 希尔排序---降序
             */
            int len= arr.length;
            if(arr == null || arr.length == 0) {  //判断数组是否为空
                System.out.println("该数组为空!");
                return;
            }
            for(int d=len/2; d>0; d=d/2){//选择增量d1=len/2,d2=d1/2...最后增量为1
                for(int i=d; i<len; i++){//从第d+1个元素,逐个对其所在组进行直接插入排序操作
                    for(int j=i-d; j>=0; j=j-d){
                        if(arr[j] < arr[j + d]) {//符合条件交换位置
                            swap(arr,j,j+d);//j+d 代表即将插入的元素所在的角标
                        }                
                    }
                }
                System.out.println("增量为"+d+"时的排序结果:");
                for(int i=0;i<arr.length;i++) {
                    System.out.print(arr[i]+" ");
                }
                System.out.println(" ");
            }
        }
        
    }

     运行截图:

  • 相关阅读:
    【POJ3237】Tree 树链剖分+线段树
    【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
    【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树
    【BZOJ1984】月下“毛景树” 树链剖分+线段树
    【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
    【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
    树形DP水题杂记
    【BZOJ1827】[Usaco2010 Mar]gather 奶牛大集会 树形DP
    【BZOJ1864】[Zjoi2006]三色二叉树 树形DP
    【BZOJ1060】[ZJOI2007]时态同步 树形DP
  • 原文地址:https://www.cnblogs.com/sengzhao666/p/11107275.html
Copyright © 2020-2023  润新知