a*算法的时间复杂度_最大时间复杂度为线性时间的中值查找算法

分析的时候真是层出不穷的新算法啊,不过也是增长知识,这个Linear Time Median Finding算法用于寻找随机序列的中间值,其最坏的时间复杂度也只有

,可以说是非常棒棒了。

主要参考了My Favorite Algorithm: Linear Time Median Finding,文章比较了三种中间值查找算法,分别是:

  1. Sort Based Median
  2. Quickselect with Random Pivots
  3. Quickselect with median pivots

1.Sort Based Median

这种算法思路很简单,先对序列进行排序,再从中取中间值即可,取中间值是一个

的时间复杂度,但排序的平均时间复杂度最快也是
(快速排序/堆排序等等)。

2.Quickselect with Random Pivots

这个算法借鉴了快速排序的内核,快速排序是一个循环的过程,每次循环选好种子点后会将所有值划分为大于种子点和小于种子点的两个集合,我们可以通过这个划分进一步缩小寻找中间值的范围。

整个算法的思路是:

  1. 选择种子点,一般随机选择序列中的某个点;
  2. 比较序列中每个值与种子点的大小将序列分为大于种子点和小于种子点的两个集合;
  3. 观察两个集合的数量,比较其差异:
    1. 如果两个集合数量相等,那么种子点为中间值;
    2. 如果大于种子点集合数量小于小于种子点集合数量,那么种子点出现在小于种子点集合中;
    3. 反之类似;

作者证明了其平均时间复杂度为

,但是,如果考虑最坏情况,即每次选取的种子点都为当时序列的最大值或最小值,那么,最终的时间复杂度是
,这是需要避免的一种情况。

3.Quickselect with median pivots

这个算法借鉴了一篇1973年的论文,真是服,那时计算机都没啥好的都能写出现在还在用的算法。

算法设计的核心目的在于Deterministic

,即时间复杂度确定为
,不应该会出现某些极端的情况时间复杂度为
,算法改进的点就是选好种子点。

具体的看这篇文章或者看论文吧,我主要讲下我怎么理解的。

关键点我认为在下面这张图片里,其中种子点是中间这个值:

图片

算法的步骤:

  1. 将数据按照5个一组的范围分为
    组;
  2. 每组求中值;
  3. 求所有组的中值的中值,将该值作为种子点;

需要理解的就是为何这么选择有用,从这张图里可以看出这么多个信息:

  1. 每个列中从上到下元素逐渐变大;
  2. 中间行上从左到右元素逐渐变大;

所以,图片中间的值111可以比左上角8个元素都要大,也比右下角8个元素都要小,定性来说不会出现种子点是最小或者最大的情况,而且因为每次都有

的元素是在两极上的,所以最极端情况种子点也会将整个序列分为
大的两个子序列,所以这样子序列的时间复杂度就为
了,作者给出的迭代方程是:

注:

表示寻找中间值的中间值,即红色椭圆那部分。但是感觉这个方程没有排序没每组的时间,其时间是线性的,每组排序时间为
,那么
组时间为

这个可以通过算法最终证明最后的时间复杂度为

。文章最终也给出了试验结果,和理论完美符合。

【已完结】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在计算机科学中,时间复杂度为 $O(n)$ 的排序算法被称为线性时间排序算法。目前有两种常用的线性时间排序算法,分别是计数排序(Counting Sort)和基数排序(Radix Sort)。 1. 计数排序 计数排序是一种非比较排序算法,其基本思想是对于给定的输入序列中的每一个元素 $x$,确定该序列中值小于 $x$ 的元素的个数,然后可以将 $x$ 直接放到第 $n+1$ 个位置上。具体步骤如下: 1. 找出待排序的数组中最大和最小的元素。 2. 统计数组中每个值为 $i$ 的元素出现的次数,存入数组 $C$ 的第 $i$ 项。 3. 对所有的计数累加(从 $C$ 中的第一个元素开始,每一项和前一项相加)。 4. 反向填充目标数组:将每个元素 $i$ 放在新数组的第 $C_i$ 项,每放一个元素就将 $C_i$ 减去 $1$。 计数排序的时间复杂度为 $O(n+k)$,其中 $n$ 是待排序序列的长度,$k$ 是待排序序列中的最大值和最小值的差。当待排序序列的最大值和最小值相差不大时,计数排序的效率比较高。 2. 基数排序 基数排序是一种多关键字比较排序算法,其基本思想是按照低位先排序,然后收集;再按照高位排序,然后再收集;依此类推,直到最高位。这样通过对每个关键字的排序,达到了整体排序的目的。具体步骤如下: 1. 取得数组中的最大数,并取得位数。 2. arr 为原始数组,从最低位开始取每个位组成 radix 数组。 3. 对 radix 进行计数排序(利用计数排序中的“每个桶里放置当前桶和前面桶的元素个数和”),从而得到排序结果。 基数排序的时间复杂度为 $O(d(n+k))$,其中 $d$ 是数字位数,$n$ 是待排序序列的长度,$k$ 是基数,通常是 $10$。当数字位数 $d$ 较小时,基数排序的效率比较高。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值