递归调用

【算法】递归

耗尽温柔 提交于 2019-12-03 12:04:44
递归是一个比较难理解的问题,但是递归是一种非常广泛的算法,如数据结构中的树和图都会应用队规的算法。一般大家会拿汉诺塔进行举例,但是还有更容易理解的例子。 周末你去看电影,然后你忘记了现在坐的是第几排了,电影院太黑了,看不清,没法数,怎么办? 这个时候就可以问递归解决了,于是你问前面的人是第几排,你想只要在他的数字上加一,就知道自己是第几排了。但是,前面的人也看不清是第几排呀,于是他也问他前面的人。就这样一排一排往前问,直到问道第一排的人,说我在第一排,这样一排一排再把数字传回来。 这是一个很标准的递归求解问题的分解过程。所有递归问题都可以用递归公式来表示。 总结一下,就是一个递归要满足三个条件: 1.一个问题的解可以分解成几个子问题的解 2.这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样 3.存在递归终止条件 即写出一个递归函数,例子如下: f(n) = f( n-1) +1 其中,f(1) = 1 改成代码为: #python 3 def f(x:int) ->int: if ( n==1): return 1 return f( n-1) +1 再举个例子,假如这里有 n 个台阶,每次可以跨一个或者俩个台阶,请问走这 n 个台阶有多少种走法? 我们仔细想一下,实际上,我们可以根据第一步的走法把所有走法分为两类,第一类是第一步走了1个台阶

20182315 第八周学习总结

走远了吗. 提交于 2019-12-03 12:03:43
学号 2019-2020-1 《数据结构与面向对象程序设计》第八周学习总结 教材学习内容总结 线性查找:可设置哨兵,将a[0]设成需要找的值,每一个元素和哨兵进行比对,可优化程序。 二分查找:二分查找的优势在于每次查找都可排除上次查找后一半的元素,极大加快查找速率。但二分查找需让数组排序,按顺序查找。 选择排序:通过二重循环,每一次找出符合条件的最值元素,将此元素放在首位。 插入排序:插入排序为依次排序,即将现插入的数字排号,以后插入的数字都在前面的排序里找到合适的位置,也采用二重循环,与选择排序相似。 冒泡排序:与之前学过的C语言相同,一次循环,经过n次比较,确定一个最值,放在开头或结尾。 快速排序:对目标进行多次分块排序,每次应用于左右两个划分快,直到每个人划分快只包含一个元素。代码中用到递归语句,if划分块中元素不多于一个时,停止递归。内层递归中,从划分块两端向中间查找,遇到错排的两个元素,交换其位置,知道left和right指针相遇时停止。递归使程序无线分裂成两个程序,直到停止为止。排序核心为:一次排序确定一个元素的位置。 归并排序:先将数表拆成几个长度为1或2的子表,再将子表排序。 教材学习中的问题和解决过程 问题1:归并排序的实现原理不够清晰,不理解几次分块后如何排序?。 问题1解决办法:相比于快速排序一次确定一个元素的位置,归并排序排的是元素块的位置,接收三个参数

python:利用递归遍历文件夹所有文件(包括子文件夹里的文件)

匆匆过客 提交于 2019-12-03 11:05:30
废话不说,先上代码: 1 import os 2 3 4 def show_files(path, all_files): 5 # 首先遍历当前目录所有文件及文件夹 6 file_list = os.listdir(path) 7 # 准备循环判断每个元素是否是文件夹还是文件,是文件的话,把名称传入list,是文件夹的话,递归 8 for file in file_list: 9 # 利用os.path.join()方法取得路径全名,并存入cur_path变量,否则每次只能遍历一层目录 10 cur_path = os.path.join(path, file) 11 # 判断是否是文件夹 12 if os.path.isdir(cur_path): 13 show_files(cur_path, all_files) 14 else: 15 all_files.append(file) 16 17 return all_files 18 19 20 # 传入空的list接收文件名 21 contents = show_files("e:\\python", []) 22 # 循环打印show_files函数返回的文件名列表 23 for content in contents: 24 print(content) 刚开始写了半天,只能遍历当前目录,要不就是递归超过最大深度

经典排序--归并排序

十年热恋 提交于 2019-12-03 10:10:37
归并排序的原理   归并排序是利用归并的思想实现的排序方法,该方法采用经典的分治策略(分治法将问题分成一些小的问题然后递归求解,而治的阶段则是将分的阶段得到的答案修补在一起,即分而治之)。 图解归并排序    下面我们以待排序数组 8,4,5,7,1,3,6,2,9,10为例,以图解的方式讲解归并排序的原理。   (1)分治原理图(由于图片太大,没法截全,我进行了一定压缩,所以看起来有点奇怪...)   从图中可以看出,归并排序是先将数组进行拆分,拆分到剩余一个关键字,这是一个从大到小的过程。然后再进行治理,治理的过程也就是进行合并的过程,合并时会保证左右两边的数组内部各自有序。然后将两个有序的数组合并到一个数组中,且合并后的数组有序。总结就是:递归拆分,回溯合并,合并时左右两个数组内部有序。   (2)递归原理图   在看递归原理图前,我们先看下归并排序的代码,如下所示 1 public class MergeSort { 2 private static int count = 1; 3 public static void main(String[] args) { 4 int[] arr = {8, 4, 5, 7, 1, 3, 6, 2, 9, 10}; 5 int[] temp = new int[arr.length]; 6 split(arr, 0, arr

递归

半城伤御伤魂 提交于 2019-12-03 10:03:46
一、递归   1、递归应用场景     递归的实际应用场景,迷宫问题(回溯),递归(Recursion)        2、递归的概念     简单的说: 递归就是方法自己调用自己 ,每次调用时 传入不同的变量 ,递归有助于编程者解决复杂的问题,同时,可以让代码更加简洁。   3、递归调用机制     递归调用机制,常见应用:     (1)打印问题 1 public static void test(int n) { 2 if (n > 2) { 3   test(n - 1); 4 } 5 System.out.println("n=" + n); 6 }     (2)阶乘问题 1 //阶乘 2 public static int factorial(int n) { 3 if (n == 1) { 4 return 1; 5 } else { 6 return factorial(n - 1) * n; // 1*2*3 7 } 8 } 9     图解:   4、递归能解决的问题     (1)各种数学问题如:八皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子的问题     (2)各种算法中也会使用到递归,比如快速排序,归并排序,二分查找,分治算法等     (3)将用栈解决的问题—>递归代码比较简洁   5、递归需要遵守的重要规则     (1)执行一个方法时

快速排序,归并排序,堆排序的数组和单链表实现

和自甴很熟 提交于 2019-12-03 07:11:42
原文链接: https://www.cnblogs.com/DarrenChan/p/8807112.html 这三个排序的时间复杂度都是O(nlogn),所以这里放到一起说。 回到顶部 1. 快速排序 # 快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 步骤为: 从数列中挑出一个元素,称为"基准"(pivot), 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 最优时间复杂度:O(nlogn) 最坏时间复杂度:O(n2) 稳定性:不稳定 从一开始快速排序平均需要花费O(n log n)时间的描述并不明显

递归函数与高阶函数

被刻印的时光 ゝ 提交于 2019-12-03 06:49:25
递归函数与高阶函数 #_author:Administrator#date:2019/11/1#1def fun(*args): print(args)a=[1,2,3]fun(*a)# (1, 2, 3)print('--------------')def fun1(**kwargs): print(kwargs)fun1(**{'name':'star'})#{'name': 'star'}直接传一个字典#2.高阶函数#(1)函数名是一个变量,可以进行赋值#(2)函数名可以做为函数的参数,还可以作为函数的返回值def f(n): return n*ndef fun2(a,b,func): return func(a)+func(b)print(fun2(2,3,f))#13print('---------------------')def fu(): def f(): return 5 return fm=fu()print(m)#<function fu.<locals>.f at 0x03719738> 是一个函数对象地址print(m())# 5print('---------------------')#3 递归函数def jie(n): if n==1: return 1 return n*jie(n-1)print(jie(5))# 120print('------

Java递归调用

房东的猫 提交于 2019-12-03 06:15:57
6.递归调用 方法的递归调用 就是方法自身调用自身。 以下程序因为递归没有结束的条件,所以一直压栈,没有弹栈,导致栈内存溢出错误!所以递归必须要有结束条件。 public class RecursionTest01{ //入口 public static void main(String[] args){ m1(); } public static void m1(){ m1(); //java.lang.StackOverflowError } } 【例题1】:不使用递归,计算1-N的求和。 public class RecursionTest02{ public static void main(String[] args){ int n = 5; //调用该方法完成1-N的求和 int retValue = method1(n); System.out.println(retValue); //15 } //该方法完成1-N的求和. public static int method1(int n){ int sum = 0; for(int i=0;i<=n;i++){ sum += i; } return sum; } } 【例题2】:使用递归,计算1-N的求和。 public class RecursionTest03{ public static void main

递归理解-汉诺塔问题

梦想与她 提交于 2019-12-03 05:34:51
汉诺塔问题 汉诺塔问题的求解可以巧妙利用递归思想 以下摘自知乎上我认为阐述得很清除回答: 要用程序来解决这个问题,我们先定义一个移动函数:move(移动数,开始柱,中转柱,目标柱), 例如 move(2,A,B,C) 表示将2个盘子从A柱(开始柱)借助B柱(中转柱)移动到C柱(目标柱)。 关于开始柱,中转柱,目标柱这三个概念可以用移动过程中的某个状态来理解, 看下面一张图应该就能明白: 有三种状态的柱子,开始柱,中间柱,目标住,开始柱指的是开始状态时存放所有盘子的柱子,中转柱指的是中间状态时暂时存放n-1个(三层就是3-1个)盘子的柱子, 目标柱指的是盘子最终要移动到的柱子。这里需要注意,开始柱,中转柱,目标柱并不是一成不变的,而是会根据层次的不同而改变。(如果这里暂时不能理解的话,先读下去,再回头你就能明白了)。 接着我们分情况讨论一下盘子的移动: 情况一 当盘子只有1个(调用 move(1,A,B,C))当盘子只有一个的时候, 只要直接将盘子从开始柱移动到目标柱就可以了,并没有中间状态(即不用借助中转柱),在move方法中可以用一句话表示该移动动作 print('A--->C'); 情况二 当盘子有2个(调用 move(2,A,B,C))这个情况分三个步骤进行: step1. 把除了最大的盘子之外的盘子从A移到BA--->B (开始柱--->中转柱) 【相当于调用 move(1

JavaSE_11_File类、递归

允我心安 提交于 2019-12-03 03:49:44
1.1 概述 File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。 1.2 构造方法 public File(String pathname) :通过将给定的 路径名字符串 转换为抽象路径名来创建新的 File实例。 public File(String parent, String child) :从 父路径名字符串和子路径名字符串 创建新的 File实例。 public File(File parent, String child) :从 父抽象路径名和子路径名字符串 创建新的 File实例。 // 文件路径名 String pathname = "D:\\aaa.txt"; File file1 = new File(pathname); // 文件路径名 String pathname2 = "D:\\aaa\\bbb.txt"; File file2 = new File(pathname2); // 通过父路径和子路径字符串 String parent = "d:\\aaa"; String child = "bbb.txt"; File file3 = new File(parent, child); // 通过父级File对象和子路径字符串 File parentDir = new File("d:\