“折半“算法的细节剖析

​前言

常见的折半算法莫过于折半查找折半插入排序,我们在此将他们的一些特点加以提炼,剖析,对比,以此实现更好的理解这种分组简化,提高效率的思想。


基本思想
​折半插入排序是建立在折半查找的基础之上的,所以在此我们先分析折半查找。

什么叫折半?其实在数学上这就叫二分法。对于一个已经有序的数组(你可以用其他方法排序,比如选择或者冒泡),这个数组中的数就像数轴上一条线段,你只要将待查的关键字(key)与中点比较大小,就可以知道key对应的这个点是落在线段的左半部分还是右半部分。之后,我们再重复这个操作,这样我们的区间就会不断缩小,最后锁定在一个数上。然后我们就会看出来,是找到了,还是没有。

二分法(折半查找)需要三个指针,right(high),left(low),mid(middle),其中前两个指针衡量查找区间的范围,mid指针实现二分(中点)。(当然,在数组里,这些指针就是index(下标)的值)

这么一来折半插入排序就很容易说明了,他就是把插入排序(先检索有序部分,再选择合适的位置插入)的遍历检索部分替换为折半查找。也就是说,先折半查找,再插入


细节


(1 )指针移动

每次折半,可以归结为三种情形(以从小到大排列的数组为例)

1.a[mid]=key,找到;

2.a[mid]<key,那么key在右半侧,只要保持right不动,left=mid+1即可;

3.a[mid]>key,这与2.恰好相反,right=mid-1;

对于折半插入排序,我们把1与2合并,至于为什么,接下来会讲。


(2)算法终点与稳定性

"折半"当然拥有高效率,但是他的终点却值得思考。

众所周知,二分法只有指定一个目标精确度,才能确定最小区间,才能有一个终点。

“折半”同理,只不过,折半处理的对象——数组是散点,使得这个终点确定更加容易。

我们用极限思维,当左右指针都指向一个数之后,还要进行最后一次比对,确定查找位置,在这之后无论是2.情况还是3.情况,Left都会移到right右边一位。

所以(left<=right)是终点条件。

把情况1合并,是为了输出,在折半插入排序中,我们以局部数组5,6,7(left指5,right指7,插入一个后方的6为例),进行试验,

若1.同2.合并:

a[mid]=key(6=6),left指向7,之后a[mid]=a[right]=a[left]>key,right指向6,到此为止,从right+1=left处开始插入。

若1.同3.合并:

a[mid]=key(6=6),right指向5,之后a[mid]=a[right]=a[left]<key,left指向6,到此为止,从right+1=left处开始插入

情况十分清楚了,只有1.同2.合并,该算法才是稳定的,6,6相对顺序不会交换,这也是为人们所选择的。


代码实现

 运行结果

 


the end

活动地址:CSDN21天学习挑战赛

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值