0
点赞
收藏
分享

微信扫一扫

插入排序(直接插入和希尔排序)

GG_lyf 2022-03-24 阅读 205

目录

写在前面的话

一,直接插入排序

1.1思路实现

一趟排序实现

整个排序实现

1.2代码实现 

1.3复杂度以及稳定性 

1.4可以改进的点

二,希尔排序

2.1希尔排序思路

第一步 分组预排序

第二步:直接插入

2.2代码实现

代码思路分析(重要)


写在前面的话

                                                  

一,直接插入排序

好的,那么首先对于插入排序来说,(升序为例)其原理就是找出小的值从后面移动到前面。

1.1思路实现

一趟排序实现:

如下图所示,那么首先我们从数组头部开始。将第一个元素下标记为 end,然后将其后面那个位置元素记为 x。(这里以升序为例,但道理都是相同的

比如,当前位置移动一次后:

最后,在一趟排序或者跳出循环之后,end 后面那个位置的元素一定是空的(或者没有移动时候的 x 元素),需要将记录的值 x 填入那个空位置(或者原先自己的位置)。

整个排序实现

1.2代码实现 

//直接插入排序
void InsertSort(int* a, int n)
{
	assert(a);
	for (int i = 0; i < n - 1; i++)
	{
		//一次while循环,一趟排序,将x之前的所有元素排成有序
		int end = i;
		int x = a[end + 1];
		while (end >= 0)
		{
			//如果end所在元素大于后面元素,则将其移动到end+1位置上,
            //然后再判断,同时为x元素腾出位置
			if (a[end] > x)
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = x;
	}
}

1.3复杂度以及稳定性 

1.4可以改进的点

二,希尔排序

希尔排序是在直接插入排序的基础上改进的,因为直接插入排序的时间复杂度确实太高了。所以希尔排序是提出了一种改进方法,减少每一次排序的次数,将时间复杂度改进到O(N)。

那么我们来具体看一下希尔排序是怎样实现的。

2.1希尔排序思路

第一步 分组预排序

下面这个序列虽然不是完全有序的,但是相比于原来的数组而言,是更加有序了。如果此时我们再进行一次预排序,那么就会更加有序,直到gap为 1 ,虽然可能不是完全有序的。

第二步:直接插入

2.2代码实现

void ShellSort(int* a, int n)
{
	assert(a);
	//多次预排序(gap > 1) +直接插入 (gap == 1)
	int gap = n;
	//gap等于 1 的时候,说明是插入排序了
	while (gap > 1)
	{
		//研究表明,gap除 3 的时候,效果更好
		//但是有时候单单除以 3 的话,有可能导致gap取不到 1
		gap = gap / 3 + 1;
		//gap = gap / 2;
		// 多组一起排
		for (int i = 0; i < n - gap; ++i)
		{
			int end = i;
			int x = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > x)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = x;
		}
	}
}

代码思路分析(重要):

好的,那么本文到此就结束啦!如果有问题的话,还请指正呀!如果觉得还不错的话,跪求三连呀!

举报

相关推荐

0 条评论