插入排序 && 希尔排序

插入排序

原理

整个区间被分为

  1. 有序区间
  2. 无序区间
    每次选择无序区间的第一个元素(bound位置),在有序区间内选择合适的位置插入
    在这里插入图片描述

实现

// 以升序排序为例
    public static void insertSort(int[] array) {
        // 有序区间: [0, bound)
        // 无序区间: [bound, size)
        for (int bound = 1; bound < array.length; bound++) {
            // 处理 bound 位置的元素如何往前插入
            int tmp = array[bound];
            // 需要从后往前, 找到合适的位置进行插入.
            int cur = bound - 1;
            for (; cur >=0; cur--) {
                // 如果这里的条件写成了 array[cur] >= tmp, 此时就是不稳定排序了
                if(array[cur] > tmp) {
                    // tmp 元素还需要往前去找. 同时就需要把 cur 位置的元素往后搬运
                    array[cur + 1] = array[cur];
                } else {
                    break;
                }
            }
            array[cur + 1] = tmp;
        }
    }

性能分析

时间复杂度 : O(N^2)
空间复杂度 : O (1)
稳定性 :稳定排序
特性 :
1、如果一个数组本身已经比较小了,此时使用插入排序效率会很高。
2、如果一个数组本身已经接近有序,此时使用插入排序效率会很高。

希尔排序

原理

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

  1. 希尔排序是对直接插入排序的优化。
  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
    在这里插入图片描述
    gap = 3 同组相邻元素下标之差也就是3
    针对每组元素分别插排后,虽然未能彻底完成最终排序,但是有序性整体提高了。
    gap = 2
    重复进行插排,此时仍然未能完成排序,但是有序性得到了进一步提高。
    gap = 1
    最后一次插排,完成排序。

实现

public static void shellSort(int[] array) {
        int gap = array.length /2;
        while (gap > 1) {
            insertSortGap(array, gap);
            gap = gap / 2;
        }
        insertSortGap(array, 1);
    }
    // 分组情况下, 同组的相邻元素下标差 gap
    private static void insertSortGap(int[] array, int gap) {
        // 从每组的 [1] 的元素开始.
        for (int bound = gap; bound < array.length; bound += gap) {
            int tmp = array[bound];
            int cur = bound - gap;// bound 位置中相邻的前一个元素下标
            for ( ; cur >= 0; cur -= gap) {
                if (array[cur] > tmp) {
                    // 进行搬运, 把 cur 位置的元素搬到 cur + gap 位置
                    array[cur + gap] = array[cur];
                } else {
                    break;
                }
            }
            array[cur + gap] = tmp;
        }
    }

性能分析

时间复杂度 :O(N^2)
空间复杂度 : O(1)
稳定性 : 不稳定排序

希尔排序效率要高,也是对插入排序的改进。

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试
应支付0元
点击重新获取
扫码支付

支付成功即可阅读