【排序】直接插入排序和希尔排序

目录

一、排序思想

1、直接插入排序

2、希尔排序

二、代码实现

三、性能比较

四、排序总结

1、直接插入排序

2、希尔排序


一、排序思想

1、直接插入排序

基本思想:把待排序的序列选取一个整数逐个插入到已经排好的有序序列中,直到所有整数都插入到这个有序序列中,得到一个新的有序序列。

2、希尔排序

基本思想:在直接插入排序的基础上进行了优化,选取一个整数gap,把每个距离为gap的数分为一组,并对每一组内的数进行预排序,得到接近有序的序列。更改gap,直到gap==1时,得到一个新的有序序列。

【排序】直接插入排序和希尔排序_第1张图片

二、代码实现

//直接插入排序
void InsertSort(int* a, int n)
{
	//先走单趟 再走整体
	//[0,end]有序,把end+1位置的值插入 保持有序
	for (int i = 0; i < n - 1; i++)
	{
		int end=i;
		int tmp = a[end + 1];
		while (end >= 0)
		{
            //排升序
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
            //只要tmp>=a[end]就跳出循环  
				break;
			}
		}
		a[end + 1] = tmp;
	}

}
//希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		 gap = gap / 3+1;
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
               //排升序
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end-=gap;
				}
				else
                   //只要tmp>=a[end]就跳出循环
					break;
			}
			a[end + gap] = tmp;
		}
	}
  }

三、性能比较

//随机生成100000个数,插入到在堆上开辟的数组中,并对该数组进行排序
//测试两个排序所用时间
void TestOP()
{
	srand(time(0));
	const int N = 100000;
	int* a1 = (int*)malloc(sizeof(int) * N);
	int* a2 = (int*)malloc(sizeof(int) * N);
	//memset(a1, 0, sizeof(int) * N);
	for (int i = 0; i < N; i++)
	{
		a1[i] = rand();
		a2[i] = a1[i];
	}

	int begin1 = clock();
	InsertSort(a1, N);
	int end1 = clock();

	int begin2 = clock();
	ShellSort(a2, N);
	int end2 = clock();

	printf("InsertSort:%d\n", end1 - begin1);
	printf("ShellSort:%d\n", end2 - begin2);

	free(a1);
	free(a2);
}
int main()
{
	TestOP();
	return 0;
}

//运行结果
InsertSort:3700
ShellSort:16

四、排序总结

1、直接插入排序

<1>、元素集合越接近有序,直接插入排序的时间效率就越高,最坏情况是逆序

<2>、时间复杂度:O(n^2)

<3>、空间复杂度:O(1)

<4>、稳定性:它是一种稳定的排序算法

2、希尔排序

<1>、希尔排序是对直接插入排序的进一步优化,当gap>1时都是进行预排序,目的是让数组更有序,当gap==1时,数组已经接近有序,整体达到对直接插入排序的优化。

<2>、时间复杂度:O(n^1.3)

<3>、空间复杂度:O(1)

<4>、稳定性:它是一种不稳定的排序算法

你可能感兴趣的:(排序算法,数据结构,算法)