2-2 插入排序(1)

来源:互联网 发布:淘宝企业店铺需要什么 编辑:程序博客网 时间:2024/06/16 14:35

  • 插入排序算法第 1 讲
    • 插入排序的大体思路
    • 代码实现
    • 插入排序与选择排序比较

插入排序算法第 1 讲

插入排序的大体思路

下面展示了插入排序的大体思想:

由此,我们可以观察到插入排序算法的特点:每 1 次循环,都能保证红色部分(排好序的部分)的数组元素个数多 1 ,未排序的数组元素个数少 1。

代码实现

我们首先先给出插入排序的算法实现(第 1 版,Java 代码实现):

Java 代码实现:

/** * 插入排序与选择排序的一个重要差别是:循环有终止的时候。 * Created by liwei on 17/5/10. */public class InsertSort implements ISortAlogorithm {    @Override    public String getName() {        return "insert sort";    }    @Override    public void sort(int[] arr) {        // 当只有 1 个元素的时候,默认是排好序的,所以从 1 开始        // 外层循环应该到最后一个元素        for (int i = 1; i < arr.length; i++) {             // 内层循环从外层循环的标定点开始,直到索引为 1 的那个元素,            // 因为索引为 1 的那个元素前面没有元素了            // 只要后面元素比前面元素小,就交换,否则退出循环            for (int j = i; j > 0; j--) {                if (arr[j] < arr[j - 1]) {                    swap(arr, j, j - 1); // 提示:每一次交换意味着 3 次复制,这里可以通过多次交换优化,具体代码实现,我们留在接下来的两小节中                } else {                    break;                }            }        }    }    private void swap(int[] arr, int index1, int index2) {        int temp = arr[index1];        arr[index1] = arr[index2];        arr[index2] = temp;    }}

测试代码:

/** * 测试: * 插入排序 */@Testpublic void testInsertSort() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {    int[] randomArray = SortTestHelper.generateRandomArray(5000, 100, 500);    SortTestHelper.testSortEfficiency(new InsertSort(), randomArray);    SortTestHelper.testSorted(randomArray);}

测试结果:

您所使用的排序算法是 => insert sort

排序算法耗时 => 0.022 秒

给定数组按照升序排序!

下面这张图展示了对上面算法核心过程的分析:

关键之处:

  1. 第 1 轮只有 1 个元素,所以元素就是排好序的,所以应该从第 2 个元素(索引为 1 的元素开始循环),直到数组的最后一个元素(这就是边界值设置为 < length)的原因;
  2. 内层循环以刚开始的那个元素作为标定点,依次与前面一个元素进行比较,如果遇到比自己大的元素,就与它交换,直到遇到等于自己或者比自己小的元素,内层循环终止
    特别说明:插入排序对于选择排序来说,它的内层循环是可以提前终止的,这一点是十分重要的。

下面是一种等价的写法:

说明:在 for 循环里面,出现 if 条件判断的分支是 break 的时候,可以把条件判断的部分放到 for 循环的循环体判断语句中。

下面,我们对“选择排序”和“插入排序”做一个比较。

“插入排序”与“选择排序”比较

(待添加)

分析:选择排序,每一次外层循环都要选出一个最小的元素排在数组的前面。而插入排序只要遇到了不大于自己的元素,内层循环就终止。所以插入排序虽然看起来会执行较少的步骤,但是插入排序每一轮会多次交换数组元素的位置,“无形之中”浪费了很多时间。下一小节,我们就针对这一点进行代码的优化,这个优化的思路(技巧)是很常见的。

原创粉丝点击