(二) 数据结构 - 插入排序

插入排序

这是基于就地比较的排序算法。在此,将始终维护一个子列表。例如,数组的下部保持被排序。要“插入”此排序子列表中的元素,必须找到其适当的位置,然后将其插入到该位置。因此,名称,插入排序。

依次搜索该数组,然后将未排序的项目移动并插入到已排序的子列表中(在同一数组中)。该算法不适用于大型数据集,因为其平均和最坏情况下的复杂度均为Ο(n^2),其中n是项数。

但是在近乎有序的数组中,效率是相当的高~~!

核心思想

我们以未排序的数组为例。

Unsorted Array

插入排序比较前两个元素。

Insertion Sort

它发现14和33都已经按升序排列。目前,已排序的子列表中有14个。

Insertion Sort

插入排序前进,将33与27进行比较。

Insertion Sort

并发现33位置不正确。

Insertion Sort

它将33与27交换。它还将检查已排序子列表的所有元素。在这里,我们看到排序后的子列表只有一个元素14,而27大于14。因此,排序后的子列表在交换后仍保持排序。

Insertion Sort

到目前为止,我们在排序后的子列表中有14和27。接下来,将33与10进行比较。

Insertion Sort

这些值不是按排序的顺序。

Insertion Sort

但是,交换使27和10未排序。

Insertion Sort

因此,我们也交换它们。

Insertion Sort

我们再次交换它们。到第三次迭代结束时,我们有了一个包含4个项目的排序子列表。

Insertion Sort

我们再次交换它们。到第三次迭代结束时,我们有了一个包含4个项目的排序子列表。

Insertion Sort

该过程一直进行到所有未排序的值都包含在已排序的子列表中为止。

代码开发

实现思路

Step 1-如果它是第一个元素,则它已经排序。返回1;
Step 2-选择下一个元素
Step 3-与排序的子列表中的所有元素进行比较
Step 4-移动排序的子列表中大于待排序的值
Step 5-插入值
Step 6-重复直到列表被排序

伪代码

package com.paal.demo.c01SortingBasic;

import com.paal.demo.Sort;
import com.paal.demo.utils.SortTestHelper;

/**
 * <p/>
 * <li>title: 基础排序-插入排序</li>
 * <li>@author: li.pan</li>
 * <li>Date: 2019/11/4 1:13 下午</li>
 * <li>Version: V1.0</li>
 * <li>Description: </li>
 */
public class InsertionSort implements Sort {


    @Override
    public void sort(Integer[] arr) {

        int n = arr.length;
        for (int i = 0; i < n; i++) {

            // 寻找元素arr[i]合适的插入位置
            // 写法1  子列表的数据一一比较交换
//            for (int j = i; j > 0; j--)
//                if (arr[j] < arr[j - 1])
//                    SortTestHelper.swap(arr, j, j - 1);
//                else
//                    break;
            // 写法2 j-- 维护子列表
            for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--)
                SortTestHelper.swap(arr, j, j - 1);

            // 写法3
//            Integer e = arr[i];
//            int j = i;
//            for (; j > 0 && arr[j - 1] > e; j--)
//                arr[j] = arr[j - 1];
//            arr[j] = e;
        }

    }

}

    /**
     * 插入排序测试
     */
    @Test
    public void insertionSortTest() {
        Integer[] integers0 = SortTestHelper.generateRandomArray(100, 0, 1000000);
        Integer[] integers1 = SortTestHelper.generateRandomArray(10000, 0, 1000000);
        Integer[] integers2 = SortTestHelper.generateRandomArray(100000, 0, 1000000);
        System.out.println("------------------------------随机数组--------------------------------");
        System.out.println("选择排序测试1数据量为100耗时: "+SortTestHelper.testSort(integers0, new SelectionSort()));
        System.out.println("选择排序测试2数据量为10000耗时: "+SortTestHelper.testSort(integers1, new SelectionSort()));
        System.out.println("选择排序测试3数据量为100000耗时: "+SortTestHelper.testSort(integers2, new SelectionSort()));
        System.out.println("插入排序测试1数据量为100耗时: "+SortTestHelper.testSort(integers0, new InsertionSort()));
        System.out.println("插入排序测试2数据量为10000耗时: "+SortTestHelper.testSort(integers1, new InsertionSort()));
        System.out.println("插入排序测试3数据量为100000耗时: "+SortTestHelper.testSort(integers2, new InsertionSort()));
    }

执行结果

------------------------------随机数组--------------------------------
选择排序测试1数据量为100耗排序时长为: 0.001s
选择排序测试2数据量为10000排序时长为: 0.09s
选择排序测试3数据量为100000排序时长为: 8.524s
插入排序测试1数据量为100排序时长为: 0.0s
插入排序测试2数据量为10000排序时长为: 0.001s
插入排序测试3数据量为100000排序时长为: 0.004s

发布了87 篇原创文章 · 获赞 69 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/lp284558195/article/details/102913590