分治算法-简单了解

部分内容来自:http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741370.html  感谢原作者!


这种将整个问题分解为若干个小问题来处理的方法称为分治法。被分解出来的小问题与原问题有相同的解法,这样便于算法的计算(往往采用递归)。

     分治法的控制流程:

  A 判断是否满足最小处理条件,或者说满足了最小规模函数,然后进行处理,或者返回。【有的可能没有】

  B 如果没有满足最小规模,那么就开始对数据进行分块处理。

  C 递归调用A过程

  D 结合一下分治后的结果。


 

1、  折半搜索

一个已经排好序的数组中寻找某一个指定元素。那么便可以折半查找,即一直比较数组中间的元素和指定元素的大小关系,然后决定了下一轮查找的范围(缩小到了一半)。此处采用的是一个循环,记录住left和right,并不断的调整lefe和right下标位置。

2、  递归求最大最小值

通过分治的思想,不断的求出一半中的最大值和最小值,然后再比较左边和右边的最小值以及左边和右边的最大值。在此处获得的想法就是看递归函数的参数如何设置,比如要算出最大值和最小值,那么便可以设置两个参数,这个参数如果是引用,那么数值在每一层递归中都可以使用到。

3、  归并排序

先提到了插入排序:思路就是从第二个位置开始扫描数组,然后把刚遇到的元素插入到前面元素中去,使得前面的元素保持一定的顺序。

归并排序就是通过分治的思想把分开后有序的串拼接到一起。分为两部分,一个是MergeSort函数,主要用于分治,然后通过Merge函数把结果合并到一起。注意的是Merge函数的参数是开始,中间位置和结束位置,是普世的位置,不是从0开始的。归并排序之所以快是因为当把一些有序的数组再合并到一起的时候更加的快捷高效。

归并排序中需要留意的地方:缩小到什么规模的时候可以结束;另外在用数组的时候涉及到频繁的移位。提出了使用链接的归并排序算法。即通过之前提到的链接图来做,而不再是数组。

 

4、快速排序

       快速排序的思想是通过分治的方式,使得某元素左边的元素总是小于分割点处的元素,而分割点处元素的右面元素都大于该元素。算法也是分为两部分,quicksort,主控制函数以及partition函数(用户对指定范围内的函数进行操作,即某元素左边小于某个值;某元素右面的元素大于某个值。)

    

   排序算法   最坏复杂度   平均复杂度

   冒泡排序    O(n2)          O(n2)

   插入排序    O(n2)          O(n2)

   选择排序    O(n2)          O(n2)

   快速排序    O(n2)          nlog(n)

               归并排序    nlog(n)         nlog(n)

      

5、选择问题:在一个数组中选出第k小的元素

        最容易想到的办法就是先排序,然后选出第k小的元素;或者采用分治的思想,采用快速排序中partition的思想,找到小于某元素的所有元素和大于该元素的所有元素。这样在再找第k个的话便更加的方便和快捷。最坏情况下的复杂度为On2,平均复杂度为On.因为知道了左边小于某元素的大概多少个,大于某元素的多少个。先笼统的划分了一个范围。需要注意的就是在partselect中要不断的调整范围。

      

         上述的方法在最差的情况下时间复杂度为O(n2),怎么进一步优化呢。在调用partition函数的时候就是为了找出分界点在哪,那么怎么能快速精确的定位分界点数据呢。可以先把整个数据进行分段,然后把每一段的中间元素放到该端的最前端,这样数组的最前面就是记录每一段的中间数据了。然后再从前段这些数据中找到中间元素。以此元素作为分界值。一面发生最坏的情况。

 

6、矩阵的乘法

两个N*N矩阵的相乘时间复杂度为On3,相加的时间复杂度为On2,这个可以通过想象代码的实现过程就可以。

        于是有人想到了采用分治的思想,就是把矩阵分成一块一块的,然后再进行分块计算。虽然思想不错,但是复杂度没有变化,还是On3。此处可以学学如何推到的时间复杂度。规模降低之后的表示方式,T(n)、T(n/2)表示,以及多出来的操作时什么,复杂度如何表示等。

        分治之后的复杂度仍然是On3,于是有人想着如何降低乘法的次数,这样便可以降低复杂度,于是有人最终通过数学推倒,发现可以把原来分治之后的八次乘法降低为七次惩罚操作和18次加减法计算。目前矩阵最好的时间复杂度是On2.36。

 

7、直线上的最接近点对问题

首先想到的方法就是把这些点先排序,然后便可以通过一遍扫描知道最接近点对。通过分治的思想解决方式如下:按照中位数分为左右两部分,然后在左右两边都找最接近点对,然后再判断两边最接近点之间的距离。从而可以找出最接近点对。

    

8、平面上最接近点对问题

同样可以通过X坐标来把所有的点分成一块一块的,然后求出每一块的最近点对。不同块之间的最近点对计算的时候就要有筛选了,不是计算所有的,而是在限定好的区域内进行选取。时间复杂度为NlogN


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值