排序算法算法之Insertion Sort
来源:互联网 发布:中文域名转码器 编辑:程序博客网 时间:2024/05/22 15:02
引言
感觉1年前写的这篇文章有些不全面,因此今天我想完善一下这篇文章。
插入排序的几大优势
毋庸置疑,Insertion Sort 与其它几个高级排序算法(quicksort, heapsort, merge sort)相比,效率要低得多。但是,它也有自己的几大优势:
- 实现简单
- 对于小数据集很有效
- 在实际应用中,它要比其它的一些
O(n2) 算法(比如:bubble sort)更有效 - Adaptive - 即它可以利用有序元素的优势
- 稳定的,即相等元素的相对顺序不变
- 原址的
实现插入排序
下图是我从 wikipedia 上找到的,它很清楚地演示了插入排序的过程。
我相信大家看过上图以后,应该很清楚排序地整个过程了吧。其实它的整个排序过程像大家玩扑克抓牌的整个过程,你左手里面的牌都是有序的,当你从桌子上抓新牌的时候,你拿它与你左手上的牌逐个进行比较,然后找到一个合适的位置并插入进去。
下面我用 Java 来实现一下 Insertion Sort.
public class InsertionSort { public static void main(String[] args) { int[] a = {5, 2, 4, 6, 1, 3}; sort(a); System.out.println("haha: " + Arrays.toString(a)); } private static void sort(int[] arr) { for (int j = 1; j < arr.length; j++) { int key = arr[j]; int i = j - 1; while (i >= 0 && key < arr[i]) { arr[i + 1] = arr[i]; i--; } arr[i + 1] = key; } }}
接下来,我用循环不变式来证明一下上面算法的正确性。
- Loop Invariant : arr[0 … j - 1] 是有序的
- Initialization : 由于从 j = 1 开始,上面循环不变式的数组中只有1个元素,这肯定是有序的
- Maintenance : for 循环内不断地把 arr[j - 1],arr[j - 2],arr[j - 3] 等向右移动,直到为 arr[j] ,即上述代码中的 key 变量,找到一个合适的位置插入进去。因此在下轮迭代前,即把
j
变量增加1之前,arr[0, j] 是有序的,当下一轮迭代开始时,即j
变量被加1以后,arr[0, j - 1] 依然保持有序 - Termination : 变量
j
的最终值将等于 arr.length ,由于我们已经说明了上面的循环不变式在每次迭代中都保持不变,因此,arr[0, j - 1] ,即arr[0, arr.length - 1] 最终将是有序的,即整个数组都是有序的
分析时间复杂度
从上面的代码可以看出,如果待排序的数组已经有序了,每次 for 循环的迭代中,都不会去进入 while 循环内执行,因此最好情况的时间复杂度为
最坏情况就是如果待排序的数组是逆序的,它的时间复杂度为
平均时间复杂度也是
通过这个时间复杂度的分析,我相信大家对我上面所说的 Insertion Sort 具有 Adaptive 的性质,会有一个更深地理解。
- 排序算法算法之Insertion Sort
- 插入排序算法Insertion-Sort
- 排序算法总结之插入排序 Insertion Sort
- 算法排序--插入排序(insertion sort)
- 经典排序算法:插入排序Insertion sort
- 排序算法---插入排序(Insertion Sort)
- 插入排序算法——Insertion Sort
- 算法导论-插入排序 insertion sort
- 使用python实现排序算法(Insertion Sort)
- 排序算法之 直接插入排序算法(Straight Insertion Sort):(Python)
- 排序算法:Insertion Sort和Merge Sort in GoLang
- 【排序算法】 插入排序 insertion sort(插入类排序)
- 经典排序算法 – 插入排序Insertion sort
- 经典排序算法 – 插入排序Insertion sort
- 基础排序算法 – 插入排序Insertion sort
- 经典排序算法 – 插入排序Insertion sort
- 经典排序算法 – 插入排序Insertion sort
- 经典排序算法 – 插入排序Insertion sort
- iOS开发设计模式详解
- 面试题11:实现函数 double Power(double base, int exponent)。求base的exponent的次方。不使用库函数。
- iOS基础知识:数组作为函数的参数
- 个人参考——android之内容提供器provider
- file_get_contents()函数报500 Internal Server Error
- 排序算法算法之Insertion Sort
- hdu1005 Number Sequence
- c++纯虚函数
- Linux命令——adduser
- asp中弹出对话框,确定后重定向方法
- 集合(下)
- leetcode 43:Multiply Strings
- ToonOneLightVF
- Java最常用的200个示例代码