排序算法学习笔记

来源:互联网 发布:java判断日期是否合法 编辑:程序博客网 时间:2024/05/15 13:53

在这用java写一下常见排序算法的读书笔记:

排序过程中用到的辅助交换函数:

public static void swap(int[] a, int indexi, int indexj) {// i和j交换int tmp = a[indexi];a[indexi] = a[indexj];a[indexj] = tmp;}


一.插入排序:

直接插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

// 插入排序static void insertSort(int[] a) {int length = a.length;for (int i = 0; i < length - 1; i++) {for (int j = i + 1; j > 0; j--) {if (a[j] > a[j - 1]) {swap(a, j, j - 1);}}}}

希尔排序是基于插入排序的一种算法, 在此算法基础之上增加了一个新的特性,提高了效率。希尔排序的时间复杂度与增量序列的选取有关,例如希尔增量时间复杂度为O(n²),而Hibbard增量的希尔排序的时间复杂度为O(n^(3/2)),希尔排序时间复杂度的下界是n*log2n。希尔排序没有快速排序算法快 O(n(logn)),因此中等大小规模表现良好,对规模非常大的数据排序不是最优选择。但是比O(n^2)
复杂度的算法快得多。并且希尔排序非常容易实现,算法代码短而简单。 此外,希尔算法在最坏的情况下和平均情况下执行效率相差不是很多,与此同时快速排序在最坏的情况下执行的效率会非常差。专家们提倡,几乎任何排序工作在开始时都可以用希尔排序,若在实际使用中证明它不够快,再改成快速排序这样更高级的排序算法. 本质上讲,希尔排序算法是直接插入排序算法的一种改进,减少了其复制的次数,速度要快很多。 原因是,当n值很大时数据项每一趟排序需要的个数很少,但数据项的距离很长。当n值减小时每一趟需要和动的数据增多,此时已经接近于它们排序后的最终位置。 正是这两种情况的结合才使希尔排序效率比插入排序高很多。

Shell排序的时间性能优于直接插入排序

希尔排序的时间性能优于直接插入排序的原因:
①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。
②当n值较小时,n和n^2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(n^2)差别不大。
③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。
因此,希尔排序在效率上较直接插入排序有较大的改进。

// 希尔排序static void shell(int[] a, int d) {int length = a.length;for (int i = 0; i < d; i++) {for (int j = i; j < length - d; j += d) {for (int k = j + d; k >= d; k -= d)if (a[k] > a[k - d]) {swap(a, k, k - d);}}}}static void shellSort(int[] a, int d) {while (d >= 1) {shell(a, d);d /= 2;}}



0 0
原创粉丝点击