插入排序

 

所谓的插入排序 , 就是将一个数目插入到该占据的位置 。就好比打扑克牌,左手拿张牌,右手每抽一张牌,将抽到的牌插入到做左手的牌中。

基本思想 :输入一个元素,插入到一个已经排好序的数列中的适当位置,使数列依然有序。

 

那么显然就会有两种办法去执行此操作 :

  第一种是去建立一个新的数组,一个元素一个元素往里面放,用新插入的元素从左到右依次比较寻找插入位置 ,当找到插入位置时将该位置及其后面的元素向后移一个单位 。

  ( 一个小例子 , 5 个数 1 , 4 , 2 , 5 , 3  , 运用此方法 ,首先将 1 放入一个新的数组 ,然后是 4 ,比 1 大 , 直接放在 1 后面 , 然后是 2 , 从左到右依次比较 , 找是否有比2大的数 ,此时会找到4 , 那么4 的位置即为要插入的位置 ,并且将4及其4后面的所有元素向后移一个单位 ) 

  (两个关键点 ,一是寻找插入位置 , 二是将插入位置及其插入位置以后的元素向后移一个单位

  代码示例:

  

void sort_cp ( ) {
	int i , j , t ; // t 用来记录插入位置  
	int a[5] = { 1 , 5 , 2 , 4 , 3 } , b[5] ; // b[5] 用来存放排好序的数组 
	
	for ( i = 0 ; i < 5 ; i++ ) {
		t = i ; // 设置插入的默认位置为 i 
		for ( j = 0 ; j < i ; j++ ) { // 寻找插入位置 
			if ( a[i] <= b[j] ) {
				t = j ;
				break ;
			}
		}
		for ( j = i ; j > t ; j-- ) { // 将插入位置及其插入位置后面的元素向后移动一个单位 
			b[j] = b[j-1] ;
		}
		b[t] = a[i] ;  // 将插入位置的元素赋值为a[i]  
	}
}

 

 

  第二种是直接在原数组上进行操作 ,假设要排列的一组数是从小到大排序 ,将每个元素依次和他前面的元素进行比较 , 若比前面的元素小 , 则进行交换 , 直到遇到前面的的数比他大 。

  ( 仍是上面的例子 ,5个数 1 , 4 , 2 , 5 , 3 , 在此数组中 从 第二个数开始 , 4 比 1 大 ,不用管 , 下一个数 2 , 2 与 4 进行比较 , 2 小于 4 , 则将 2 与 4 进行交换 , 在用 2 与 1 比较 , 2 大于 1 , 此时停止交换 , 依次类推 ) 

 

  代码示例 :

 

void sort_cp_2 ( ) {
	int i , j ;
	int a[5] = { 1 , 5 , 2 , 4 , 3 } ;
	
	for ( i = 0 ; i < 5 ; i++ ) {
		for ( j = i ; j > 0 ; j-- ) { // 对于每次新插入的元素 , 将其与它前面的元素进行比较 , 若不符合排序顺序 , 则进行交换 
			if ( a[j] < a[j-1] ) {
				t = a[j] ;
				a[j] = a[j-1] ;
				a[j-1] = t ;
			}
			if ( a[j] >= a[j-1] ) break ;  // 当发现前面的元素都是有序时 ,则停止向前检索 
		}
	}
}

 

时间复杂度 :

  考虑两种极端 , 第一种是 所要插入排序的数列是有序的 , 则时间复杂度为 O(0)

         第二种是所要插入的数列完全是逆序 ,则从第二个元素开始每次交换1次 , 2次 , 3 次 …… n-1 次 , 所以总和为 (n^2 - n) / 2 , 即时间复杂度为 O ( n ^ 2 ) 。   

posted @ 2017-08-06 00:44  楼主好菜啊  阅读(208)  评论(0编辑  收藏  举报