插入排序与希尔排序

目录

直接插入排序

折半插入排序

希尔排序


直接插入排序

时间复杂度:O(N²)

空间复杂度:O(1)

直接插入排序(Straight Insertion Sort)的过程是将一个记录插入到已经排好序的有序表中,从而得到一个新的有序表。具体细节看代码:

void DirectInsertSort(vector& nums)//直接插入排序
{
	int end = nums.size();
	//用后面的位置做下标
	for (int cur = 1; cur < end; cur++)
	{
		int i, temp = nums[cur];
		//先逐个后移,最后直接将temp放到下标停止的位置
		for (i = cur; i >= 1 && nums[i - 1] > temp; i--)
		{
			nums[i] = nums[i - 1];
		}
		nums[i] = temp;
	}
}

折半插入排序

折半插入排序也叫二分插入排序,就是将原来枚举查找的过程换成了二分查找,但效率并没有明显的提高,时间复杂度还是O(N²)。具体细节看代码:

int HalfSearch(vector nums, const int num, const int beg)
{
	int left = 0, right = beg;
	while (left <= right)
	{
		int mid = left + ((right - left) >> 1);
		if (nums[mid] < num)
			left = mid + 1;
		else if (nums[mid] > num)
			right = mid - 1;
		else return mid;
	}
	return left;
}
void HalfInsertSort(vector& nums)  //折半插入排序
{
	int end = nums.size();
	for (int cur = 1; cur < end; cur++)
	{
		int temp = nums[cur];
		int insert_posi = HalfSearch(nums, nums[cur], cur);
		for (int i = cur; i > insert_posi; i--)
		{
			nums[i] = nums[i - 1];
		}
		nums[insert_posi] = temp;
	}
}

希尔排序

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

希尔排序相较于插入排序,主要是通过引入一个增量序列来对数组进行分组,将分组后的子序列进行插入排序。由于增量序列的特殊选取,希尔排序能够以较快的速度提高插入排序的效率,并且时间复杂度为O(n^1.3)左右,相较于插入排序的O(n^2)显著得到了优化。

简单粗暴的来讲,希尔排序就是将一次大插入排序的工作递归的分成了很多小的插入排序,然后在最后整个序列接近有序的情况下再插入排序一次,这种情况下一般在数据量较大的时候表现的比插入排序要好。具体细节看代码:

void ShellSort(vector& nums)
{
	int step = nums.size(); //步长
	while (step > 0)
	{
		int end = nums.size();
		step /= 2;
		for (int index = 0; index < step; index++)
		{
			for (int cur = index; cur < end; cur += step)
			{
				int i, temp = nums[cur];
				//先逐个后移,最后直接将temp放到下标停止的位置
				for (i = cur; i >= step && nums[i - step] > temp; i -= step)
				{
					nums[i] = nums[i - step];
				}
				nums[i] = temp;
			}
		}
	}
}

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