蓝桥杯python基础算法(2-2)——基础算法(C)——递归

四、递归

递归出口:这是递归过程中的终止条件,防止函数无限制地调用自身。

当前问题如何变成子问题:这是递归函数中最重要的部分,即如何将当前问题逐步简化为更小的子问题。

例题-汉诺塔

Hanoi塔由n个大小不同的圆盘和三根木柱a,b,c组成。开始时,这n个圆盘由大到小依次套在a柱上,如图所示。要求把a柱上n个圆盘按下述规则移到c柱上:

(1)一次只能移一个圆盘;

(2)圆盘只能在三个柱上存放;

(3)在移动过程中,不允许大盘压小盘。

问将这n个盘子从a柱移动到c柱上,输出如何移动?

样例输入:1

样例输出:A->C


定义函数 Move,表示n个盘子,从A挪到C,中间通过B来挪动 Move(n, A, B, C)

考虑n个盘子的时候,将上面n-1个盘子看做一个整体

1、首先需要将n-1个盘子从A挪到B,通过C,这就变成了递归的问题Move(n-1, A, C, B);

2、然后移动:A->C

3、最后将n-1个盘子从B挪到C,通过A,Move(n-1,B,A,C);

4、n=0的时候,递归出口 

# 将n个盘子从(起始柱子)借助(辅助柱子)移到(目标柱子)
def Move(n,A,B,C):
    if n==0:
        return
    # 将n-1个盘子从A借助C移到B
    Move(n-1,A,C,B)
    # 打印将剩余的一个第n个盘子从当前起始柱子直接移动到目标柱子的操作
    print("{}->{}".format(A,C))
    # 将n-1个盘子从B借助A移到C
    Move(n-1,B,A,C)

n = 2  # 可以修改为任意正整数
Move(n, 'A', 'B', 'C')

例题 P760


输入一个自然数 n (n≤1000),我们对此自然数按照如下方法进行处理:

  1. 不作任何处理;

  2. 在它的左边加上一个自然数,但该自然数不能超过原数的一半;

  3. 加上数后,继续按此规则进行处理,直到不能再加自然数为止。

问总共可以产生多少个数。

输入描述

输入一个正整数 n。

输出描述

输出一个整数,表示答案。


n=int(input())

def f(n):
    if n==1:
        return 1
    num=1
    for i in range(1,n//2+1):
        num+=f(i)
    return num

print(f(n))

练习


1、独立写一遍快速排序、归并排序

2、利用快速排序的思想,在平均时间复杂度为O(n)的情况下,写出第k大算法。(输入n、k,一个长度为n的数组a,求第k大)


  • 快速排序是一种分治算法。它选择一个基准值(pivot),将数组分为两部分,使得左边部分的元素都小于等于基准值,右边部分的元素都大于等于基准值。然后递归地对左右两部分进行排序。

  • 归并排序也是分治算法。它将数组分成两个子数组,分别对两个子数组进行排序,然后将排序好的子数组合并成一个有序的数组。

  • 平均时间复杂度为O(n)的情况下找到第k大的元素,通过快速排序的分区操作,将数组分为两部分,根据分区点的位置与k的关系,决定在左半部分还是右半部分继续查找。只对包含目标元素的那部分子数组进行进一步处理,而不是像快速排序那样对两部分都进行排序。

def quick_sort(array):
    if len(array)<=1:
        return array
    pivot=array[0]
    left=[]
    right=[]
    for num in array[1:]:
        if num<=pivot:
            left.append(num)
        else:
            right.append(num)
    return quick_sort(left) + [pivot] + quick_sort(right)
def merge_sort(array):
    if len(array)<=1:
        return array
    mid=len(array)//2
    left=merge_sort(array[:mid])
    right=merge_sort(array[mid:])
    return merge(left,right)

def merge(left,right):
    result=[]
    i=j=0

    while i
def find_largest_k(array,k):
    # 快速选择算法中的分区函数,用于将数组划分为两部分,
    # 使得左边部分的元素都大于等于基准元素,右边部分的元素都小于基准元素。
    def partition(array,low,high):
        pivot=array[high]
        i=low-1
        for j in range(low,high):
            if array[j]>=pivot:
                i+=1
                array[i],array[j]=array[j],array[i]
        array[i+1],array[high]=array[high],array[i+1]
        return i+1

    low,high=0,len(array)-1
    while low<=high:
        pivot_index=partition(array,low,high)
        # 数组的索引是从 0 开始的,第 k 大元素,这里的计数是从 1 开始的
        if pivot_index==k-1:
            return array[pivot_index]
        elif pivot_index>k-1:
            high=pivot_index-1
        else:
            low=pivot_index+1

你可能感兴趣的:(Python,Lanqiao,算法)