zoukankan      html  css  js  c++  java
  • python专题 --- 递归

    如果一个函数在函数内部调用自身本身,这个函数就是递归函数

    举例如阶乘函数,其数学递归定义如下:

    对应的算法实现

    def fact(n):
        if n==1:
            return 1
        return n * fact(n - 1)

    实际的执行过程为:

    ===> fact(5)
    ===> 5 * fact(4)
    ===> 5 * (4 * fact(3))
    ===> 5 * (4 * (3 * fact(2)))
    ===> 5 * (4 * (3 * (2 * fact(1))))
    ===> 5 * (4 * (3 * (2 * 1)))
    ===> 5 * (4 * (3 * 2))
    ===> 5 * (4 * 6)
    ===> 5 * 24
    ===> 120

    对应的思路图为:

     

    递归函数特性:

    1. 必须有一个明确的结束条件;
    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
    3. 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)。
    4. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

    递归的概念很简单,下面对遇到的几个递归实例进行总结,以方便后续回顾:

    1. 二分查找

    2. 快速排序

    3. 遍历多重列表元素

    4. 汉诺塔

    # 方法一:
    def quicksort1(nums):
        if len(nums) <= 1:
            return nums
    
        # 左子数组
        less = []
        # 右子数组
        greater = []
        # 基准数
        base = nums.pop()
    
        # 对原数组进行划分
        for x in nums:
            if x < base:
                less.append(x)
            else:
                greater.append(x)
    
        # 递归调用
        return quicksort1(less) + [base] + quicksort1(greater)
    
    # 方法二
    def quick_sort3():
        def fast_sort(li):
            if len(li) > 1:
                l, mid ,r = deal(li)
                return fast_sort(l) + [mid] + fast_sort(r)
            else:
                return li
    
        def deal(li):
            left = 0
            right = len(li) - 1
            temp = li[-1]
            tab = True
    
            while left < right:
                if tab:
                    if li[left] <= temp:
                        left += 1
                    else:
                        li[right] = li[left]
                        tab = not tab
                        right -= 1
                else:
                    if li[right] >= temp:
                        right -= 1
                    else:
                        li[left] = li[right]
                        tab = not tab
                        left += 1
            else:
                li[left] = temp
            return li[:left], temp, li[right+1:]
    
    # 方法三:
    def quick_sort2():
        def quick(li,left,right):
            if left<right:
                mid=partition(li,left,right)
                quick(li,left,mid-1)
                quick(li,mid+1,right)
            return li
    
        def partition(li,left,right):
            pivot=li[left]
            while left<right:
                while left<right and pivot<li[right]:
                    right-=1
                li[left]=li[right]
    
                while left<right and pivot>li[left]:
                    left+=1
                li[right]=li[left]
            li[left]=pivot
            return left
    

    折半查找

    # 折半查找
    l = list(range(0, 100, 2))
    s = 85
    
    # 方法一:
    def cut_find(key, l, start=0):
        mid = len(l) // 2
        if len(l) >= 1:
            if l[mid] == key :
                return f'in position: {start+mid+1}'
            elif l[mid] > key:
                return cut_find(key, l[:mid], start)
            else:
                return cut_find(key, l[mid+1:], mid)
        else:
            return 'Can not find'
    
    print(cut_find(51, li, 0))
    
    # 方法二:
    def search(li,key,low,high):
        mid=(low+high)//2
        if key==li[mid]:
            return mid
        if low>high:
            return -1
        if key<li[mid]:
            return search(li,key,low,mid-1)
        else:
            return  search(li,key,mid+1,high)
    

    拆分多重列表元素:

    li = []
    def all(l):
        global li
        if not isinstance(l, int):
            for i in l:
                all(i)
        else:
            li.append(l)
        return li

    汉诺塔:

  • 相关阅读:
    git的使用
    每个JavaScript开发人员应该知道的33个概念
    JavaEE实战——XML文档DOM、SAX、STAX解析方式详解
    Java-函数式编程(三)流(Stream)
    Spring高级装配(二) 条件化的bean
    Spring高级装配(一) profile
    Spring Bean装配学习
    Java7任务并行执行神器:Fork&Join框架
    Stream:java1.8新特性
    java基础
  • 原文地址:https://www.cnblogs.com/geoffreyone/p/9899761.html
Copyright © 2011-2022 走看看