排序算法——插入排序的图解、代码实现以及时间复杂度分析
2018-01-21 15:47
525 查看
插入排序
插入排序的原理:插入排序由N-1躺排序完成,对于p=1到N-1躺,插入排序保证从位置0到位置p的元素为已排序状态。
插入排序的代码实现:
/** * 插入排序的实现例程,特点是使用了泛型,可以接受任何实现了Comparable接口的类, * 并且使用了一种巧妙的方法避免了交换操作。 * @param a 需要排序的数组 * @param <AnyType> 数组的类型 * @return 返回已经排好序的数组 */ public static <AnyType extends Comparable<? super AnyType>> AnyType[] insertionSort(AnyType a[]){ int p; for (int i=1;i<a.length;i++){ AnyType tmp=a[i]; /* 为什么要加上a[p]<a[p-1]这个循环控制条件呢? 因为要让p停留在正确的位置,方便将tmp赋值 这种方法避免了交换,全程只有赋值 */ for (p=i;p>0 && tmp.compareTo(a[p-1])<0 ; p--){ a[p]=a[p-1]; } a[p] = tmp; } return a; }
由于嵌套循环的每一个都花费N次迭代,因此插入排序为O(N2),而且这个界是精确的。如果输入数据已预先排序,那么运行时间为O(N),因为内层循环的检测总是立即判定不成立而终止。事实上,如果输入几乎有序,那么插入排序将运行得很快。插入排序的平均情形是θ(N2)。
逆序数是具有如下性质的序偶:i小于j但a[i]大于a[j]的序偶(a[i],a[j])。
逆序数的个数正好是需要由插入排序执行的交换次数。由于算法中还有O(N)量的其他工作,因此插入排序的运行时间是O(I+N),其中I为原始数组的逆序数。
定理7.1 N个互异数的数组的平均逆序数是N(N-1)/4.
这个定理意味着插入排序平均是二次的,同时也提供了只交换相邻元素的任何算法的一个很强的下界。
定理7.2 通过交换相邻元素进行排序的任何算法平均都需要Ω(N2)时间。
这个定理不仅对隐含地执行相邻元素交换的插入排序有效,而且对诸如冒泡排序和选择排序等其他一些简单算法也是有效的。事实上,它对一整类只进行相邻元素的交换的排序算法,包括那些未被发现的算法,都是有效的。
这个下界告诉我们,为了使一个排序算法以亚二次(subquadratic)或O(N2)时间运行,必须执行一些比较,特别是要对相距较远的元素进行交换。
相关文章推荐
- 排序算法——快速排序的图解、代码实现以及时间复杂度分析
- 排序算法——希尔排序的图解、代码实现以及时间复杂度分析
- 插入排序和归并排序实现以及时间复杂度分析
- 排序算法的C语言实现以及各个算法的时间复杂度和空间复杂度分析(冒泡排序)
- 常见排序算法的C语言实现以及算法复杂度分析(持续更新)
- 算法 插入排序 的 JS实现及时间复杂度分析
- 找出数组中第k大的数(时间复杂度分析、C++代码实现). TopK in array. ( leetcode - 215 )
- 快速排序算法原理,实现,以及时间复杂度分析
- c语言实现线性表的建立,初始化,插入,删除,查找,遍历以及时间复杂度分析
- 浅谈直接插入排序算法思想以及时间复杂度分析
- MIT:算法导论——4.2快速排序 以及 排序算法时间复杂度分析
- 快速排序实现以及时间复杂度分析
- 各种常用排序的时间复杂度和稳定性以及代码实现
- 找工作知识储备(3)---从头说12种排序算法:原理、图解、动画视频演示、代码以及笔试面试题目中的应用
- 素数判断的几种方法代码实现及其复杂度分析
- 二分法实现插入排序,时间复杂度O(nlgn),算法导论练习2.3,linux纯C实现
- 哈夫曼树分析以及代码实现
- 几种排序算法的时间复杂度分析
- 排序算法 (稳定性时间复杂度分析)
- 用内核定时器来实现的按键驱动代码分析以及测试代码