插入排序--折半插入排序(来一来,看一看,走过路过,不要错过)

  人生没有彩排,每天都是现场直播,不仅收视率低,而且工资不高。



一.前言

  插入排序根据查找插入位置的方式不同可以分为三类:按顺序法查找插入位置的——直接插入排序;按折半法也叫二分法查找插入位置的——折半插入排序;缩小增量多遍插入排序的——希尔排序。本文探讨有关折半插入排序的知识。


二.思想及操作分析

思想:
  借助二分查找的思想,先查找插入位置,再移动数据,最后插入到正确的位置。
  我们都知道直接插入排序是一个边比较边移动的过程,而折半插入排序是先确定插入的位置,再来进行移动。
  插入排序的效率是由比较的次数和移动的次数共同决定的,而折半插入排序就是通过降低比较的次数来提高排序的效率。一起看看是如何进行操作的。

操作图解分析:
  有一组数据如下,现在我们需要将这组数据按从小到大进行排序。
在这里插入图片描述
  将这一组数据分为有序组(有颜色的)和无序组(没有颜色的),数据的第一个元素默认为有序,如下:
在这里插入图片描述
  将无序组中1号位置的数据进行拷贝,同时将1号位置收编到有序组序列中。此处将被拷贝位置的数据进行抹去方便进行分析,如下:
在这里插入图片描述
  接着采用折半查找在有序组中查找插入位置,低地址端为有序组的第一个位置(记为:low),高地址端为有序组的最后一个有效元素的位置(记为:high),中端地址为mid=(low+high)/2,如下:
在这里插入图片描述
  将94和mid所指位置上的元素进行比较,发现94>81,则low=mid+1,如下:
在这里插入图片描述

  当high小于low时,则low所指的位置即为插入位置,low所指的位置即1号位置此时并没有有效数据则不需要进行移动,直接进行插入,如下:
在这里插入图片描述

  继续从无序中将2号位置的数据进行拷贝,同时将二号位置收编到有序组的序列,依旧抹去2号位置的数据如下:
在这里插入图片描述
  high指向有序组最后一个有效数据的位置,low指向有序组的第一个位置,mid为两者和的二分之一,如下:
在这里插入图片描述
  将11和mid所指位置的元素进行比较,11<81,说明11要放在81的前面。high=mid-1,此时high变为-1,不大于low则low所指的位置即为要插入的位置。而此时low所指的位置存在有效元素,那么我们需要将有序组中low所指位置的数据及其后面位置的数据整体移动一个位置,如下:
在这里插入图片描述
  将11插入到low所指的位置中,如下:
在这里插入图片描述
  重复上面的操作,直至整个数据变为有序。给出最终的结果,如下:
在这里插入图片描述

  每一次将无序组中的元素插入到有序组,都是通过二分查找法确定该元素会插入到有序组的哪一个位置后,再看该位置有没有被有效元素占据,没有就直接插入,有则将该位置元素及其后面位置的元素整体移动一个位置,再进行插入。


三.代码设计

基本步骤:
1.将数据进行分组,有序组和无序组;
2.从无序组中拷贝第一个位置的数据,采用二分查找法查找出该元素将要插入到有序组的哪一个位置;
3.将查找到的位置中的数据及其后面的数据整体移动一个位置;
4.将数据插入到查找到的位置;
5.重复2、3、4直到整个数据变为有序。

  大的方向可以将该算法分为三部分,第一部分:从无序组中取元素的操作;第二部分:采用二分查找法查找插入位置的操作;第三部分:移动元素空出插入位置,再将数据插入的操作。


四.代码实现

typedef int ElementType;
void BinaryInsertSort(ElementType array[], int size)
{
	int high;//高地址位置
	int low;//低地址位置
	int mid;//中端位置
	int i;//指示无序组中的元素位置
	int j;//指示有序组中的元素位置
	ElementType temp;//临时变量,用于拷贝数据
	for (i = 1; i < size; i++)//第一个位置默认有序
	{
		temp = array[i];//拷贝数据
		high = i - 1;//指向有序组中最后一个有效数据
		low = 0;//指向有序组中第一个数据位置
		while (low<=high)//采用二分查找,在有序组中找待插入元素的位置
		{
			mid = (low + high) / 2;//中间位置为low于high和的一半
			if (array[mid] < temp)//说明插入位置在mid的右边
			{
				low = mid + 1;//指向比较位置的后一个位置
			}
			else//说明插入位置在mid的左边
			{
				high = mid - 1;//指向比较位置的前一个位置
			}
		}
		for (j = i; j >=low; j--)//将查找的位置元素及其后面的元素整体移动一个位置
		{
			array[j] = array[j - 1];
		}
		array[low] = temp;//插入到正确位置
	}
}

五.总结

  折半插入排序通过减少元素比较次数使得排序效率得到提高。由于二分查找比顺序查找快,所以折半插入排序的平均性能来说比直接插入排序要好。
  时间复杂度为O(n^2),空间复杂度为O(1),是一种稳定的插入排序

如何提高插入排序的效率:
减少元素的比较次数
减少元素的移动次数

  下期我们讲解通过减少元素的比较次数和移动次数来提高插入排序效率的——希尔排序


  我是老胡,感谢阅读!!❤️ ❤️

  • 82
    点赞
  • 289
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
1. 快速排序的算法思想: 快速排序是一种基于分治思想的排序算法,它的基本思路是通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个过程可以递归进行,以达到整个序列有序的目的。具体步骤包括: 1)选择一个基准元素,将待排序序列分成两部分,一部分的所有元素都比基准元素小,另一部分的所有元素都比基准元素大。 2)递归地对这两部分子序列进行快速排序,直到整个序列有序。 2. 直接插入排序算法思想: 直接插入排序是一种简单的排序算法,它的基本思想是将待排序的数据逐个插入到已经排好序的有序序列中,直到所有数据都插入到有序序列中为止。具体步骤包括: 1)将第一个元素看作是有序序列,将第二个元素插入到有序序列中,使得这两个元素组成一个有序序列。 2)将第三个元素插入到已经排好序的序列中,以此类推,直到所有元素都插入到有序序列中。 3. 折半插入排序算法思想: 折半插入排序是一种改进的直接插入排序算法,它的基本思想是在已经排好序的序列中,采用二分查找的方式找到待排序元素应该插入的位置,从而减少了插入的比较次数,提高了排序的效率。具体步骤包括: 1)将第一个元素看作是有序序列,将第二个元素插入到有序序列中,使得这两个元素组成一个有序序列。 2)将第三个元素插入到已经排好序的序列中,采用二分查找的方式找到待排序元素应该插入的位置,以此类推,直到所有元素都插入到有序序列中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值