排序算法—希尔排序

1.希尔排序的算法思想

  • 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

2.简单总结下希尔排序的基本思路:

  • 先取一个小于n的整数gap1(一般为 n/3 +1)作为第一个增量,把数组全部记录分组。所有距离为 gap1 的倍数的记录放在同一个组中。先在每一小组内进行直接插入排序;然后,取第二个增量 gap2 < gap1 重复上述的分组和排序,直至所取的增量 = 1 ( < …

  • 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序,走完后数组变为有序。

  • 希尔排序图解
    排序算法—希尔排序_第1张图片

  • 以升序为例基本代码实现如下:

void Shellsert_Sort(int* arr, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;//一般是gas/3,最后一定要记得 +1!!!
		//注意:在选取步长的时候必须保证最后一个增量必须为1,这样才能保证希尔排序的正确性
		for (int i = 0; i < n - gap; i++)
			//思考:为什么 i < n - gas,因为步数最多的那一个的最后一个元素下标是n - gas;
		{
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (tmp < arr[end])
				{
					arr[end + gap] = arr[end];
					end = end - gap;
				}
				else
				{
					break;
				}
			}
			//注意最后end的变化,当初在这里没注意end的变化导致理解了很久!!!
			arr[end + gap] = tmp;
		}
	}
}
void ShellSort_test()
{
	int arr[] = { 4, 3, 2, 8, 0, 9, 7, 8, 5, 4, 8, 9, 5, 6, 4 };
	int n = sizeof(arr) / sizeof(int);
	Shellsert_Sort(arr, n);
	printf("希尔排序结果:");
	for (int i = 0; i < n; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main()
{
	ShellSort_test();
	system("pause");
	return 0;
}

3.直接选择排序的特性总结

  • 时间复杂度分析(该排序事假复杂度较为复杂)

    ①:最优情况下时间复杂度:O( n^1.3 ).

    ②:最差情况下时间复杂度:O( n^2 ).

  • 空间复杂度分析

    直接选择排序空间复杂度为:O( 1 ).

  • 稳定性分析
    由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的

  • . 希尔排序是对直接插入排序的优化

你可能感兴趣的:(Data-Struct)