排序算法之插入排序( 直接插入 & 希尔 )

插入排序基本思想 : 每一步将一个待排序的元素,按其排序码的大小,插入到前面已经排好序的一组元素的合适位置上去,直到元素全部插完为止。

【直接插入排序】:当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序 进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移

 如上图所示各趟排序后的结果 : 

  • 元素集合越接近有序, 直接插入排序算法的时间复杂度越高
  • 最优的情况下 : 时间复杂度为 O(n)
  • 最差的情况下 : 时间复杂度为 O(n^2)
  • 空间复杂度 : O(1) , 它是一种稳定的排序算法

【希尔排序】: 又称缩小增量排序,是对直接插入排序的优化 , 如下图所示 , 以3为间隔 , 每次进行排序 , 使数组接近于有序 ,

这样就能减少元素后移的次数 , 这样在大量数据排序时 , 效率会大大提高 ; 在下面的测试中会有明显的差别

代码如下 : 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
//直接插如排序
void InsertSort(int *a, int len)
{
	assert(a);
	//由于end是从i+1开始进行排序的n,所以i要小于len-1
	for (int i = 0; i < len - 1; i++){
		int end = i+1;
		//使用临时变量记录end下标的值
		int tmp = a[end];
		//如果end下标的值小于i当前下标的值,则进行元素后移
		if (a[end] < a[i]){
			//由于是在已经排序好的数组插入元素,所以后移的结束条件为
			//当end走到数组最开始的位置和临时变量不小于end-1代表的元素时
			while (end > 0 && tmp < a[end - 1]){
				a[end] = a[end-1];
				end--;
			}
		}
		//将临时变量放到end所走到的位置
		a[end] = tmp;
	}
}
//希尔排序(缩小增量排序)
void ShellSort(int *a, int len)
{
	assert(a);
	int idx = len;
	while (idx > 1)
	{
		//idx为每次插入排序所需要的间隔
		idx = idx / 3 + 1;
		for (int i = 0; i < len - idx; i++){
			int end = i + idx;
			int tmp = a[end];
			if (a[end] < a[i]){
				//注意:这里的判断条件和直接插入不同,由于希尔排序是跳跃式的插入排序
				//所以这里end的结束不是数组的最开始,而是i
				while (end > i && tmp < a[end - idx]){
					a[end] = a[end - idx];
					end -= idx;
				}
			}
			a[end] = tmp;
		}
	}
}
void Printf(int *a, int len)
{
	assert(a);
	for (int i = 0; i < len; i++)
		printf("%d ", a[i]);
	printf("\n");
}
int main()
{
	int a[100000] = { 0 };
        int b[100000] = { 0 };
	srand(time(0));
	for (int i = 0; i < 100000; i++){
		b[i] = a[i] = rand();
        }
	int begin1 = clock();
	InsertSort(a, sizeof(a)/sizeof(int));
	int end1 = clock();
	int begin2 = clock();
	ShellSort(b, sizeof(b) / sizeof(int));
	int end2 = clock();
        //比较直接插入排序和希尔排序的效率
        printf("直接插入排序所需要的时间 : %d ms\n", end1 - begin1);
	printf("希尔排序所需要的时间 : %d ms\n", end2 - begin2);
	system("pause");
	return 0;
}

在上面的代码中随机生成了100000个数据用直接插入排序和希尔排序分别进行测试 , 调试结果如下 : 

若有出错或不懂的地方,​ 欢迎留言, 共同进步 !

猜你喜欢

转载自blog.csdn.net/ds19980228/article/details/82589860