您的位置:首页 > 编程语言

排序算法——插入排序的图解、代码实现以及时间复杂度分析

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)时间运行,必须执行一些比较,特别是要对相距较远的元素进行交换。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐