把一个复杂的问题分解两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接解决,原问题的解即子问题的解的合并
[1] 分治思想
将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之
[2] 适用情况
- 规模缩小到一定程度更容易解决
- 问题分解成若干小规模相同子问题, 问题具有***最优结构性质***
- 小规模问题可以合并求出该问题的解
- 各个子问题相互独立
- 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
- 无后效性。即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响。
- 子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
[3] 归并排序
将待排序的元素分为大小大致相同的集合, 分别对两个子集合进行排序, 最终排序号的子集合合并为有序集合
归并排序是八大排序算法其中一种(快速、堆、冒泡、希尔、归并、桶、选择、插入), 归并采用分而治之的思想对排序序列,分解成不可再分的子序列,再对子序列向上合并
# 分割部分
from random import shuffle
from math import floor
def merge_sort(arr):
import math
if len(arr) < 2:
return arr
# 数据向下取整
middle = floor(len(arr) / 2)
# 左右分割
left, right = arr[0:middle], arr[middle:]
# 对左右进行递归合并
return merge(merge_sort(left), merge_sort(right))
#合并部分
def merge(left,right):
result = []
while left and right:
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0));
while left:
result.append(left.pop(0))
while right:
result.append(right.pop(0));
return result
# 格式化输出
def output(arr):
index = 1
for a in arr:
print('%-6d' % a, end=' ')
if index % 16 == 0:
print('\n')
index += 1
if __name__ == '__main__':
arr = [x * x for x in range(80)]
shuffle(arr)
print('='*50, '洗牌后数据', '='*50)
output(arr)
print('='*50, '排序后数据', '='*50)
output(merge_sort(arr))
[4] 参考链接