极简算法_插入排序

Posted 野区杰西

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了极简算法_插入排序相关的知识,希望对你有一定的参考价值。

简介

插入排序它不是一种专指一种排序,它包括了常见的直接插入排序以及希尔排序

基本思想

插入排序的基本思想是,每次将一个待排序的记录按其关键字的大小插入到前面已排好序的文件中的适当位置,直到全部记录插入为止

直接插入排序

直接插入排序的思想非常简单,就将待排序的记录存在数组 target[1..n] 中,在排序的过程中将 taget 分为两个部分:target[1..i-1] 和 target[i..n]。我们可以将前面的部分当作排好序的有序区,而后面是无序区。排序的过程中,仅仅需要每次从无序区中取出第一个元素,把它插入有序区的适当位置,使之称为新的有序区,依次这样经过 n-1 次插入后,无序区为空,有序区中包含了全部 n 个元素,至此排序完毕。

废话不多说,下面是算法实现

public class InsertSort {

    
/**
     * 直接插入排序
     * @param target    目标数组
     * @param n         数组长度
     */

    
void insertSort(int[] target, int n) {
        
int i, j;
        
//开始循环数组
        
for (i=2; i<n; i++) {
            
//目前我们要找到一个下标大的比下标小的值小的
            
if (target[i] < target[i-1]) {
                
//记录在哨兵的位置
                target[
0] = target[i];
                
//开始将 target[0] 在有序区寻找插入的位置
                
for (j=i-1;target[0]<target[j];j--) {
                    
//同时记录需要往后移动
                    target[j+
1] = target[j];
                }

                
//最后将插入正确的位置
                target[j+
1] = target[0];
            }

        }

    }

}

然后是测试类

class Test {
    public static void main(String[] args) {
        int[] target = new int[]{046,39,17,23,28,55,18,46};
        new InsertSort().insertSort(target, target.length);
        for (int i = 0; i < target.length; i++) {
            System.out.print("     " + target[i]);
        }
    }
}

从算法处理的过程中,我们可以发现待排序的 target 的首位,是不参与排序的。实际上,target[0] 不参与排序的原因有两个:

  1. 进入查找之前保存 target[i] 的副本
  2. 用来监视循环中数组下边变量 j 是否越界。也就是当 target[0] 和自身比较的时候,使循环条件不成立而结束循环。因此,常把 target[0] 称为哨兵。

看完实现后,我们可以使用一组数据来演示,假设数据为 [47, 37, 12, 24, 29, 53, 16, 46]

首先是初始化数据

[47] [37, 12, 24, 29, 53, 16, 46]

然后是第一趟排序

[37, 47] [12, 24, 29, 53, 16, 46]

然后是第二趟排序

[12, 37, 47] [24, 29, 53, 16, 46]

然后是第三趟排序

[12, 24, 37, 47] [29, 53, 16, 46]

然后是第四趟排序

[12, 24, 29, 37, 47] [53, 16, 46]

然后是第五趟排序

[12, 24, 29, 37, 47, 53] [16, 46]

然后是第六趟排序

[12, 16, 24, 29, 37, 47, 53] [46]

然后是第七趟排序

[12, 16, 24, 29, 37, 46, 47, 53]

希尔排序

希尔排序,同时又名缩小增量排它是直接排序算法的一种更高效的改进版本,希尔排序是非稳定排序算法。

希尔排序的主要思想在于,先取定一个小于 n 的整数 d1 作为第一个增量,把数组 target 中的全部元素分成 d1 个组,所有下标距离为 d1 的倍数的元素放在同一个组中,即 target[1]target[1+d1]target[1+2d1]target[1+3d1]...为第一组,target[2]target[2+d1]target[2+2d1]...作为第二组,...。然后各组内进行直接插入排序;然后再取 d2(d2<d1) 为第二个增量,重复上述分组和排序,知道所有的增量 dt=1dt<dt-1<...<d2<d1) 为止。最后将所有的元素放在同一组中进行直接插入排序为止。

把记录按下表的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。

    public void binSort(int[] array) {
        int gap = array.length;
        while (true) {
            gap /= 2;   //增量每次减半
            for (int i = 0; i < gap; i++) {
                for (int j = i + gap; j < array.length; j += gap) {//这个循环里其实就是一个插入排序
                    int temp = array[j];
                    int k = j - gap;
                    while (k >= 0 && array[k] > temp) {
                        array[k + gap] = array[k];
                        k -= gap;
                    }
                    array[k + gap] = temp;
                } 
            }
            if (gap == 1)
                break;
        }
    }

然后是测试类

    public static void main(String[] args) {
        int[] array = {49,38,65,97,76,13,27,49,78,34,12,64,1};

        System.out.println("排序之前:");
        System.out.println();
        for (int i=0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }

        new BinSort2().binSort(array);

        System.out.println();
        System.out.println("排序之后:");
        System.out.println();
        for(int i=0;i<array.length;i++){
            System.out.print(array[i]+" ");
        }
    }

完!


以上是关于极简算法_插入排序的主要内容,如果未能解决你的问题,请参考以下文章

排序算法(3/4) 之 插入排序_md

算法_基本排序算法之冒泡排序,选择排序,插入排序和希尔排序

7种基本排序算法的Java实现

算法题 14 LeetCode 147 链表的插入排序

算法导论第八章__实现计数排序

算法排序