递归式问题解决D&C

分而治之思想
使用D&C解决问题的过程包括两个步骤:
1.找出基线条件,这种条件必须尽可能简单;
2.不断将问题分解(缩小问题规模),直到符合基线条件。
举例:给定一个数字数组,将这些数字相加返回结果。
使用循环方法:

def sum(arr):
	total = 0
	for x in arr:
		total +=x
		return total
		print sum([1,2,3,4])

如何使用递归函数方法呢??
第一步:找出基线条件。最简单的数组什么样呢?–数组中不包含元素,或只含有一个元素,求和最容易。
第二步:每次递归调用使其离空数组更近一步,,缩小问题规模。
sum([2,4,6])===2 + sum([4,6])
描述:对于一个列表。若列表为空,就返回0;否则,计算列表中第一个元素与除去第一个元素的其他数字的求和。
Tips:涉及数组的递归函数时,基线条件通常是数组为空或只包含一个元素

#数组元素求和
def sum(arr):
    if(arr == []):
        return 0
    else:
        return arr[0]+sum(arr[1:])
print(sum([1,2,3,4,5,6,7,8,9,10]))

递归函数计算列表中包含的元素数

#列表中元素的个数
def count(arr):
    if (arr == []):
        return 0
    else:
        return 1+count(arr[1:])
print(count([1,2,3,4,5,6,7]))

找出列表中最大的数字(这一个开始没有想到,所谓最大是在一次次地比较中得出的)

#第一个元素与后面元素比较,选出最大的
def maxNum(arr):
    if len(arr)==2:#最简单时候,只有两个元素,比较一下选出大的数
        if(arr[0]>arr[1]):
            return  arr[0]
        else:
            return arr[1]
    else:#第一个元素与后面元素的整体进行比较,从而缩小问题的规模
        if(arr[0]>maxNum(arr[1:len(arr)])):
            return arr[0]

        else:
            return maxNum(arr[1:len(arr)])

print(maxNum([1,2,3,4,5,6,8]))

最后让我们再仔细回想二分查找中包含的递归思想以及涉及的条件

def search(list,item):
        low = 0
        high = len(list) - 1
        #最简单的情况,数组中只包含一个元素,若要查找的值与这个元素相同就找到了
        while(low<=high):
            mid=int((low+high)/2)
            if(list[mid]<item):#舍弃左边一半,对右半部分进行二分查找,即缩小了问题规模
                low = mid + 1
            elif(list[mid]>item):
                high = mid - 1
            else:
                return mid

        return None
my_list = [1,2,3,4]
print (search(my_list, 1))
print (search(my_list, 2))

二分查找的递归条件中,把数组分为两半,将其中一半丢弃,并对另一半执行二分查找。
快速排序也使用了D&C
对排序算法来说,最简单的数组为空或只包含一个元素,在这时,根本不用排序
排序的原理:
在数组中选择一个元素作为基准值,接着找到比基准值小的元素和比其大的元素进行分区。
part1:小于基准值的数字的子数组;
part2:基准值
part3:大于基准值的数字的子数组;
对子数组进行快速排序,再合并结果,可得有序数组
包含三个元素的数组可以进行排序,在此基础上递归地快速排序,经过归纳证明,以此类推,快速排序对任何长度的数组都管用。

#快速排序
def quicksort(arr):
    if len(arr)< 2:#基准条件:空或只含两个元素的数组是有序的
       return arr
    else:
        pivot = arr[0]#递归条件
        left = [x for x in arr[1:] if x <= pivot]#小于基准值构成的子数组
        right = [x for x in arr[1:] if x > pivot]#大于基准值构成的子数组
        return quicksort(left)+[pivot]+quicksort(right)
print(quicksort([10,5,2,3]))

快速排序在以基准值进行划分时,在调用栈的每层都涉及O(n)个元素
最佳情况(平均情况):O(nlogn)
最糟情况:o(n^2)
只要每次都随机地选择一个数组元素作为基准值,快速排序的平均运行时间就为O(nlogn).快速排序是最快的排序算法之一,也是D&C典范。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值