算法简析之插入排序

简析


概念

插入排序(Insertion sort) 插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。 插入排序方法分直接插入排序和折半插入排序两种。

直接插入排序 把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。

折半插入排序(binary insertion sort) 是对插入排序算法的一种改进,由于排序算法过程中,就是不断的依次将元素插入前面已排好序的序列中。由于前半部分为已排好序的数列,这样我们不用按顺序依次寻找插入点,可以采用折半查找的方法来加快寻找插入点的速度。

直接插入排序原理

假设待排序的记录存放在数组a[0…n-1]。

  1. 初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令i=1

  2. 将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间。

  3. i++并重复第二步直到i==n-1。排序完成。

折半插入排序原理

  1. 将待插入区域的首元素设置为a[low],末元素设置为a[high],则轮比较时将待插入元素与a[m]

  2. 其中m=(low+high)/2相比较,如果比参考元素小,则选择a[low]到a[m-1]为新的插入区域(即high=m-1),否则选择a[m+1]到a[high]为新的插入区域(即low=m+1)

  3. 如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入a[high+1]。


范例(java)


概念代码

    //直接插入排序
 public static void main(String[] args) {

    int arr[] = {23, 44, 56, 21, 32, 55, 74, 13};
    int count = arr.length;
    for (int i = 1; i < count; i++) {
        int temp = arr[i];
        int position = i;
        for (int j = i - 1; j >= 0; j--) {
            if (arr[j] > temp) {
                arr[j + 1] = arr[j];
                position -= 1;
            } else {
                break;
            }
        }
        arr[position] = temp;

        System.out.print("第" + i + "次排序结果:");
        for (int anArr : arr) {
            System.out.print(anArr + "\t");
        }
        System.out.println("");

    }

    System.out.print("最终排序结果:");
    for (int anArr : arr) {
        System.out.print(anArr + "\t");
    }
}
1
2
3
4
5
6
7
8
第1次排序结果:23	44	56	21	32	55	74	13	
第2次排序结果:23 44 56 21 32 55 74 13
第3次排序结果:21 23 44 56 32 55 74 13
第4次排序结果:21 23 32 44 56 55 74 13
第5次排序结果:21 23 32 44 55 56 74 13
第6次排序结果:21 23 32 44 55 56 74 13
第7次排序结果:13 21 23 32 44 55 56 74
最终排序结果:13 21 23 32 44 55 56 74
    //折半插入排序
  public static void main(String[] args) {

    int arr[] = {23, 44, 56, 21, 32, 55, 74, 13};
    int count = arr.length;
    int middle = 0;
    for (int i = 1; i < count; i++) {
        int low = 0;
        int high = i - 1;
        int temp = arr[i];

        while (low <= high) {
            middle = (low + high) / 2;
            if (temp < arr[middle]) {
                high = middle - 1;
            } else {
                low = middle + 1;
            }
        }

        int k = i;
        while (k > middle) {
            arr[k] = arr[k - 1];
            k--;
        }

        arr[high + 1] = temp;   //此处用 arr[low] = temp ;也可

        System.out.print("第" + i + "次排序结果:");
        for (int anArr : arr) {
            System.out.print(anArr + "\t");
        }
        System.out.println("");

    }

    System.out.print("最终排序结果:");
    for (int anArr : arr) {
        System.out.print(anArr + "\t");
    }
}
1
2
3
4
5
6
7
8
第1次排序结果:23	44	56	21	32	55	74	13	
第2次排序结果:23 44 56 21 32 55 74 13
第3次排序结果:21 23 44 56 32 55 74 13
第4次排序结果:21 23 32 44 56 55 74 13
第5次排序结果:21 23 32 44 55 56 74 13
第6次排序结果:21 23 32 44 55 56 74 13
第7次排序结果:13 21 23 32 44 55 56 74
最终排序结果:13 21 23 32 44 55 56 74