zoukankan      html  css  js  c++  java
  • 小橙书阅读指南(四)——希尔排序及改进算法

    算法描述:希尔排序是一种基于插入排序的快速排序算法,相比于传统的相邻插入,希尔排序更加适合大规模乱序数组的排序。和插入算法一样,我们也可以优化插入和移动的过程从而进一步提升算法效率。

    算法图示:

    希尔排序算法的实质是首先将一个大的乱序数组变成几个小的有序数组,再逐步调整数组长度。最后一步依然是做一次传统意义上的插入排序,只不过经过之前的调整以后,需要移动的元素不会离当前距离太远。

    以下是希尔排序算法的动态示意图:

    Java代码示例:

    package algorithms.sorting;
    
    import algorithms.common.Arrays;
    import algorithms.common.ArraysGenerator;
    import algorithms.Sortable;
    
    import java.io.IOException;
    
    /**
     * Created by learnhow on 2018/8/13.
     */
    public class Shell extends Arrays<Integer> implements Sortable<Integer> {
        @Override
        public void sort(Integer[] array) {
            int h = 1;
            while (h < array.length / 3) {
                h = 3 * h + 1;
            }
            while (h >= 1) {
                for (int i = h; i < array.length; ++i) {
                    for (int j = i; j >= h; j -= h) {
                        if (array[j] < array[j - h]) {
                            exchange(array, j, j - h);
                        }
                    }
                }
                h = h / 3;
            }
        }
    
        public static void main(String arg[]) throws IOException {
            Integer[] arr = ArraysGenerator.generateDesc(1000, 5000);
            Shell shell = new Shell();
            shell.sort(arr);
            System.out.println(java.util.Arrays.toString(arr));
            System.out.println(ArraysGenerator.isSort(arr, "asc"));
        }
    }

    Qt/C++代码示例:

    void Shell::sort(int * arr, int len)
    {
        int h = 1;
        while (h < len / 3) {
            h = 3 * h + 1;
        }
    
        while (h >= 1) {
            for (int i = h; i < len; ++i) {
                for (int j = i; j >= h; j -= h) {
                    if (arr[j] < arr[j - h]) {
                        int tmp = arr[j];
                        arr[j] = arr[j - h];
                        arr[j - h] = tmp;
                    }
                }
            }
            h = h / 3;
        }
    }

    算法改进:实际上传统的插入排序和希尔排序影响性能的主要问题是为了达到排序的目的,一个元素可能需要经过多次交换(每次交换动作都需要3次赋值操作)。因此改进的关键是如何减少元素交换或减少赋值操作。当然这会增加算法的难度。

    Java代码示例:

    package algorithms.sorting;
    
    import algorithms.Sortable;
    import algorithms.common.ArraysGenerator;
    
    import java.util.Arrays;
    
    /**
     * Created by learnhow on 2018/8/16.
     */
    public class ShellTR implements Sortable<Integer> {
        @Override
        public void sort(Integer[] array) {
            int h = 1;
            while (h < array.length / 3) {
                h = 3 * h + 1;
            }
            while (h > 0) {
                for (int i = h; i < array.length; i++) {
                    int temp = array[i];
                    int j = i;
                    while (j >= h && array[j - h] > temp) {
                        array[j] = array[j - h];
                        j -= h;
                    }
                    array[j] = temp;
                }
                h = h / 3;
            }
        }
    
        public static void main(String[] args) {
            Integer[] arr = ArraysGenerator.generateDesc(100, 100);
            ShellTR shellTR = new ShellTR();
            shellTR.sort(arr);
            System.out.println(Arrays.toString(arr));
            System.out.println(ArraysGenerator.isSort(arr, "asc"));
    
        }
    }

    Qt/C++代码示例(略)

    相关链接:

    Algorithms for Java

    Algorithms for Qt

  • 相关阅读:
    设计模式之-工厂方法模式
    设计模式之-简单工厂模式
    设计模式之-单例模式
    Ubuntu-18.04 下使用Nginx搭建高可用,高并发的asp.net core集群
    Ubuntu-18.04 下修改root用户密码,安装SSH服务,允许root用户远程登录,安装vsftp服务器
    ASP.NET Core 系列[1]:ASP.NET Core 初识
    .net core系列之《将.net core应用部署到Ubuntu》
    动态内存分配函数
    C++ sort()对结构体排序
    STL
  • 原文地址:https://www.cnblogs.com/learnhow/p/9496565.html
Copyright © 2011-2022 走看看