分而治之
分而治之是一种将复杂问题分解成更容易解决的小问题,然后将这些答案组合起来解决原来的问题的方法。分治法是一种强大的算法设计技术,用于解决许多重要问题,如<一个目标="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/merge/">归并排序一个>,<一个目标="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/quick-sort/">快速排序一个>,计算<一个目标="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/fibonacci-series/">斐波纳契数一个>以及执行<一个href="//www.parkandroid.com/wiki/matrix-multiplication/" class="wiki_link" title="矩阵乘法" target="_blank">矩阵乘法一个>.还有许多问题是人类天生使用分治法来解决的,比如对一叠扑克牌进行分类,或者在电话簿中查找电话号码。
分而治之
分而治之可以分为三个步骤,分(分成子),征服(通过解决子问题),以及结合(解决原问题的答案)。分治有一个<一个目标="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/recursion-problem-solving/">递归一个>步骤,在这里解决子问题,以及基本情况,即问题不能进一步分解的点。
分治法的直觉
你怎么点一副牌?
有许多问题的例子,人类自然采取分而治之的方法。假设你有一堆扑克牌,你想把它们按顺序排列。对整个牌组进行排序是最初的问题,但我们可以通过一次只比较一些牌将其分解为子问题。
要做到这一点,从未排序的牌组中取出第一张和第二张牌并对它们进行排序。从未排序的牌组中取出另一张牌,将其排序到已排序的牌组中。一直这样做,直到整个牌组被排序。在这里,我们通过一次只对一些卡片进行排序来划分子问题。在每一步中,我们从未排序列表中取出一张牌(除法步骤),并将其放入已排序列表中(这构成了征服和合并步骤)。
分:
分解步骤将原始问题分解为子问题,这些子问题是原始问题的小实例。
征服:
征服步骤解决子问题<一个目标="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/recursion-problem-solving/">递归地一个>.
结合:
组合步骤将已解决的子问题放在一起来解决原问题。
减少和征服
还有一种分治法,将问题简化为一个子问题。<一个href="//www.parkandroid.com/wiki/binary-search/" class="wiki_link" title="二分查找" target="_blank">二分查找一个>是一个流行的例子,使用减少和征服。二分查找查找已排序的列表,以查看列表中是否存在所需元素。它通过在程序的每次迭代期间减半搜索空间有效地做到了这一点。基本上,二分查找查找列表的中间,问“我要查找的元素比这个大还是小?”然后将列表切成两半,只在元素较小的情况下搜索左侧列表,在元素较大的情况下搜索右侧列表。它重复这个过程,直到找到它要查找的元素(或者报告该元素根本不在列表中)。
描述你将如何使用递减和征服方法在一本350页的教科书中找到第88页。
把书翻到任意一页。如果你翻开的页码大于88,把一些页码翻到书的开头(如果页码小于88,把一些页码翻到书的结尾)。现在看看你翻到的新页码。如果数量少于88,翻转一定这本书的末尾(你把数量应该减少每次迭代,因为你不想失去进步的过度),如果数量大于88,把一些对这本书的开始的页面数。重复,直到你找到88页。
使用分治法
如何使用分治法:
- 给定一个问题,找出若干小得多的子问题。
- 递归地解决每个子问题(这样做直到子问题是一个基本情况)。
- 将这些解决方案组合成一个解决主要问题的方案。
应用程序
计算机科学:
分治算法通常遵循一种通用模式:它们解决规模问题
通过递归地解决
子问题的大小
,然后把这些答案结合起来
时间。这种一般形式可以用下列递归关系表示:
的<一个目标="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/master-theorem/">主定理一个>可用于求解闭形式解的递归关系。
递归关系有助于确定算法的效率。
使用分而治之的示例实现
这里有一个例子<一个目标="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/merge/">归并排序一个>, Python中的分治算法。
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
这里有一个例子<一个目标="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/binary-search/">二分查找一个>, Python中的一个reduce and conquer算法。[1]一个>
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
参考文献
- , .二叉搜索.检索日期:2016年4月1日<一个href="https://interactivepython.org/runestone/static/pythonds/SortSearch/TheBinarySearch.html">http://interactivepython.org/runestone/static/pythonds/SortSearch/TheBinarySearch.html一个>