插入排序

插入排序是一种内部排序,所以空间复杂度为01)并不增加额外的空间,并且是稳定的排序,时间复杂度为0n2);插入排序对于每个元素Pj来说,总是比较 次,所以

 = 0n2);

  插入排序之所以复杂,关键在于比较和挪动位置的次数的增加,这也是能够优化的地方。所以,插入排序适合于集合元素中秩的和比较小,或者元素的个数不多(n<= 30)的情况。

 

插入排序代码:

//默认情况下将元素保存到1到n下标

struct Record { // 为了考察排序的稳定性,定义元素是结构体类型
	int key;
	int otherinfo;
};
typedef struct Record elementType;

void insert(elementType a[], int j)      // a保存待排序的集合, j表示插入元素的序号
{
	int temp = a[j].key;
	a[0].key = temp;                //省去判断循环是否越界的步骤
	while (a[--j].key > temp)  a[j + 1] = a[j];
	a[j + 1].key = temp;
}
void insertSort( elementType a[ ], int n )    //a保存待排序的集合,n表示集合的大小
{
	for (int i = 2; i <= n; i++)
	{
		insert(a, i);
	}
}


 


 

改进插入排序:

  为了降低在有序列表中查找合适位置的操作次数,并且减少移位操作,在查找位置中利用有序的特性用折半查找,物理实现用链表实现以减少移位操作。(但是两者不能结合使用,因为链表在查找中间元素时所花时间必然是0n),其实用链表存放元素过程中就可以让其一直保持有序的特性,但复杂度也是进阶0n2)).

 

折半插入排序:

 

void insert(elementType a[], int j)      // a保存待排序的集合, j表示插入元素的序号
{
	int low = 1,high = j - 1;
	elementType temp = a[j];
	while(low <= high)
	{
		int m = (low + high) / 2;
        if(a[m].key > temp.key)// 把与a[j]相同的元素放到低端,从而保持稳定性
        	high = m - 1; 
        else
        	low = m + 1;
	}
	
	for(int i = j-1; i>=high+1; --i) a[i+1] = a[i];
    a[high+1] = temp;
}

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


你可能感兴趣的:(插入排序)