八大排序算法---希尔排序原理及代码

冒泡排序
选择排序
直接插入排序
快速排序
归并排序
基数排序
堆排序

希尔排序

算法原理:(希尔排序又称缩小增量排序。)

基本思想:先将原表按增量ht分组,每个子文件按照直接插入法排序。同样,用下一个增量ht/2将文件再分为子文件,再直接插入法排序。直到ht=1时整个文件排好序。

关键:选择合适的增量。

希尔排序算法9-3:可以通过三重循环来实现。

图解:首先每隔一定的步长,选择一组数据,每组两个数,并将其进行比较后,排序

八大排序算法---希尔排序原理及代码_第1张图片

实例分析

1.选取间隔为4

八大排序算法---希尔排序原理及代码_第2张图片

2.选取间隔为2

八大排序算法---希尔排序原理及代码_第3张图片

3.选取间隔为1

请添加图片描述

增量的选取为了更有效率出现了克努特序列

h=h*3+1;//1,4,13,40,121,364

package com.sort;

import java.util.Arrays;

public class xier_sort {
    public static void main(String[] args) {
        //希尔排序:他是对插入排序的一个优化,核心思想就是合理的选取增量,经过一轮排序后,就会让序列大致有序
        //
        int[] arr={46,55,13,42,17,94,5,70};
        shellsort(arr);
        System.out.println(Arrays.toString(arr));
    }


    public static void shellsort(int[] arr){

        //定义一个增量
        //方案1
//        int h= 4;
//        for (int i = h; i < arr.length; i++) {
//            for (int j = i; j > h-1; j-=h) {
//                if (arr[j] < arr[j-h]){
                    int t = arr[j];
                    arr[j] = arr[j-1];
                    arr[j-1] = t;
//                    swapValue(arr,j,j-h);
//                }
//            }
//        }
//
//        h= 2;
//        for (int i = h; i < arr.length; i++) {
//            for (int j = i; j > h-1; j-=h) {
//                if (arr[j] < arr[j-h]){
                    int t = arr[j];
                    arr[j] = arr[j-1];
                    arr[j-1] = t;
//                    swapValue(arr,j,j-h);
//                }
//            }
//        }
//
//        h= 1;
//        for (int i = h; i < arr.length; i++) {
//            for (int j = i; j > h-1; j-=h) {
//                if (arr[j] < arr[j-h]){
                    int t = arr[j];
                    arr[j] = arr[j-1];
                    arr[j-1] = t;
//                    swapValue(arr,j,j-h);
//                }
//            }
//        }

//        for (int h = 4; h > 0; h/=2) {
//            for (int i = h; i < arr.length; i++) {
//                for (int j = i; j > h-1; j-=h) {
//                    if (arr[j] < arr[j-h]){
//                        swapValue(arr,j,j-h);
//                    }
//                }
//            }
//        }
        //方案2
        //希尔排序的思想,合理的选取这个增量
        //第一次这个增量选取数组长度的一半,然后不断的减半
//        for (int h = arr.length/2; h > 0; h/=2) {
//            for (int i = h; i < arr.length; i++) {
//                for (int j = i; j > h-1; j-=h) {
//                    if (arr[j] < arr[j-h]){
//                        swapValue(arr,j,j-h);
//                    }
//                }
//            }
//        }

        //方案3
        //我们第一次的增量选择数组长度的一半,还不是很好,我们可以使用一种序列叫做克努特序列
        //int h=1;
        //h=h*3+1;//1,4,13,40,121,364
        //根据克努特序列选取我们第一次的增量
        int jiange = 1;
        while (jiange<=arr.length/3){
            jiange=jiange*3+1;
        }
        //System.out.println(jiange);
        for (int h = jiange; h > 0; h=(h-1)/3) {
            for (int i = h; i < arr.length; i++) {
                for (int j = i; j > h-1; j-=h) {
                    if (arr[j] < arr[j-h]){
                        swapValue(arr,j,j-h);
                    }
                }
            }
        }

    }

    public static void swapValue(int[] arr,int i,int j){
        int t=arr[i];
        arr[i]=arr[j];
        arr[j]=t;
    }
}

你可能感兴趣的:(排序算法,算法,数据结构)