经典算法(8)- 插入排序(Insertion Sort) 及三个基本排序算法的比较

插入排序的基本思想是每次取右边的第一个元素,将它与左边已经排好序的元素一一比较,如果该元素比第j个元素大,就将该元素插入到第j和第j+1个元素之间。
最坏的情况下(比如输入序列是个逆序),每个元素都需要跟左边已经排好序的所有元素比较,总的比较次数为:1+2+...+(n-2)=(n-1)(n-2)/2 ~ O(n^2); 插入操作需要将插入位置右边的元素平移一个位置,总得移动操作次数也为O(n^2)。


插入排序是稳定的(stable),这与选择排序不同(选择排序用的是交换非相邻元素位置,所以不稳定),并且如果原序列基本上排好序的情况下,比较和移 动操作的次数可以大大降低,因为它只需比较一部分元素,在这种情况下,它与冒泡排序和选择排序不同在于: 冒泡排序需要依次比较元素直到最右端,即使左边的元素已经全部排好序也要依次比较;选择排序也需要查找右边最小的元素,即使有右边的元素已经排好序也要逐 个比较。插入排序的这个特性可以用被别的排序算法(比如quicksort)利用。

选择排序优于插入排序的地方可能就是前者的交换操作(即写操作)平均复杂度是O(n),而后者是O(n^2),所以在n很大时,想比较而言,选择排序写操作次数非常少。但是选择排序的缺点是不稳定(unstable)。

冒泡排序的写操作是O(n^2),比较操作在任何情况下(除非左边已经排好序,提前退出)都是O(n^2),效率极低。

总而言之,插入排序是三个复杂度为O(n^2)的排序算法(插入排序,选择排序和冒泡排序)中比较优的。


以下是该算法的一个实现。在代码中变量j之所以放在外面,是因为语句A[j+1] = tmp;不能放在语句break;之前位置,因为像输入序列为逆序时,比如(2,1),整个内层循环执行完,而没有执行到break语句。

/**
 * 
 * @author ljs
 * 2011-05-31
 * 
 * Insertion Sort: O(n^2) 
 *
 */
public class InsertionSort {
	public static void solve(int[] A){
		int n = A.length;
		
		for(int i=1;i<n;i++){	
			int tmp = A[i];
			int j = i-1;
			for(;j>=0;j--){
				//compare the i-th element with each of the sorted elements
				if(tmp>A[j]){						
					break;
				}else{
					A[j+1] = A[j];
				}
			}
			//stop at j-th element: insert i-th element
			//between j-th and (j+1)-th element.
			A[j+1] = tmp;
		}
	}
	
	public static void main(String[] args) {
		
		int[] A= {2,1};
		InsertionSort.solve(A);
		for(int i=0;i<A.length;i++){
			System.out.format(" %d", A[i]);
		}
		
		System.out.format("%n");
		
		A=new int[] {1,3,10,9,2,7,19,5,20,4,8,11};
		InsertionSort.solve(A);
		for(int i=0;i<A.length;i++){
			System.out.format(" %d", A[i]);
		}
		
	}
}

测试:
 1 2
 1 2 3 4 5 7 8 9 10 11 19 20

转载于:https://www.cnblogs.com/ljsspace/archive/2011/06/05/2073382.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值