小橙书阅读指南(四)——希尔排序及改进算法
算法描述:希尔排序是一种基于插入排序的快速排序算法,相比于传统的相邻插入,希尔排序更加适合大规模乱序数组的排序。和插入算法一样,我们也可以优化插入和移动的过程从而进一步提升算法效率。
算法图示:
希尔排序算法的实质是首先将一个大的乱序数组变成几个小的有序数组,再逐步调整数组长度。最后一步依然是做一次传统意义上的插入排序,只不过经过之前的调整以后,需要移动的元素不会离当前距离太远。
以下是希尔排序算法的动态示意图:
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++代码示例(略)
相关链接: