递归函数

python使用递归函数输出嵌套列表中的每个元素

a 夏天 提交于 2019-11-29 18:28:41
A = [1, 2, ["a", "b", [11, 22, 33, ("@", "$"), [111, 222, {"k1": "k1"}, {1001, 1002, 1003}]], "c"], 5, 6] def GetAll(li): for item in li: if isinstance(item, (tuple, list, dict, set)) == True: GetAll(item) else: print(item) GetAll(A) ​A = [1, 2, ["a", "b", [11, 22, 33, ("@", "$"), [111, 222, {"k1": "k1"}, {1001, 1002, 1003}]], "c"], 5, 6] def getitem(l, level=0): for item in l: if isinstance(item, (tuple, list, dict, set)): getitem(item, level + 1) else: for tab in range(level): print('\t', end='') print(item) getitem(A) #根据嵌套关系,显示缩进 ​ isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。 isinstance() 与

Java实现八大排序算法

巧了我就是萌 提交于 2019-11-29 15:20:30
本文对常见的排序算法进行了总结。 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排序算法,他们之间关系如下: \[ \begin{cases}内部排序 \begin{cases}插入排序\begin{cases}直接插入排序\\希尔排序\end{cases}\\选择排序\begin{cases}简单选择排序\\堆排序\end{cases}\\交换排序\begin{cases}冒泡排序\\快速排序 \end{cases}\\归并排序\\ 基数排序\end{cases}\\外部排序 \end{cases} \] \[ \left\{\begin{matrix} 内部排序\\ 外部排序 \end{matrix}\right. \] 稳定与非稳定 : 如果一个排序算法能够保留数组中重复元素的相对位置则可以被称为是 稳定 的。反之,则是 非稳定 的。 直接插入排序 基本思想 通常人们整理桥牌的方法是一张一张的来,将每一张牌插入到其他已经有序的牌中的适当位置。在计算机的实现中,为了要给插入的元素腾出空间,我们需要将其余所有元素在插入之前都向右移动一位。 算法描述 一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: 从第一个元素开始,该元素可以认为已经被排序

二叉树算法题

断了今生、忘了曾经 提交于 2019-11-29 15:20:30
二叉树层次遍历 //思路 特殊情况 ,根节点为null,深度为0,return 0 借助队列,队列储存每一层的所有节点, 先保存数组长度,用于控制依次遍历循环——遍历每一个节点保存值,该节点的所有子结点从队尾入队,访问过的节点从头出队 注意——需要先把width存下来,用于for循环的结束标志,因为for循环里面直接操作了queue,不能去都不敢动态获取 队列初始值为root,对每一层都要进行上述遍历——while循环控制,队列空代表叶节点这一层遍历完成,此时遍历结束,退出循环 每次循环开始前初始化一个curNodes储存该层所有节点,每次循环结束,将curNodes压入result var levelOrder = function(root) { if (root === null) return []; //空树 var result = [], queue = [root]; while (queue.length) { let width = queue.length; //需要先把width存下来,用于for循环,for循环里面直接操作了数组 let curNodes = []; for (let i = 0; i < width; i++) { let node = queue.shift(); curNodes.push(node.val); node.left ?

2-路归并排序的非递归写法

亡梦爱人 提交于 2019-11-29 05:36:15
《算法笔记》中摘取 2-路归并排序的非递归写法主要考虑到这一点:每次分组时组内元素个数上线都是2的幂次。于是就可以想到这样的思路:令步长step的初值为2,然后减数组中每个step个元素作为一组,将其内部进行排序(即把左step / 2个元素与右step / 2个元素合并,而若元素个数不超过step / 2,则不操作);再令step 乘以 2,重复上面的操作,直到step / 2超过元素个数n。 const int maxn = 100; //将数组A的[L1, R1]与[L2, R2]区间合并为有序区间(此处L2记为R1 + 1) void merge(int A[], int L1, int R1, int L2, int R2) { int i = L1, j = L2; //i指向A[L1], j指向A[L2] int temp[maxn], index = 0; //temp临时存放合并后的数组,index为其下标 while(i <= R1 && j <= R2) { if(A[i] <= A[j]) { //如果A[i] <= A[j] temp[index++] = A[i++]; //将A[i]加入序列temp } else { //如果A[i] > A[j] temp[index++] = A[j++];//将A[j]加入序列temp } } while(i <

无限类递归函数

早过忘川 提交于 2019-11-28 22:45:28
res=[] def get_son(data,parent_id=0,level=0,is_clear=True): if is_clear==True: res.clear() for item in data: if parent_id==item['parent_id']: item['level']=level res.append(item) get_son(data,parent_id=item['category_id'],level=level+1,is_clear=False) return res all_son_list=[] def get_son_list(data,p_id,is_clear=True): if is_clear: all_son_list.clear() if p_id != 0: all_son_list.append(p_id) for item in data: if item['parent_id']==p_id: all_son_list.append(item['cat_id']) get_son_list(data,p_id=item['cat_id'],is_clear=False) return all_son_list 来源: https://www.cnblogs.com/zhouze/p/11431739

递归与函数调用详细解读

为君一笑 提交于 2019-11-28 21:55:38
草稿箱存不下你了 1、函数的调用 当一个函数运行期间调用另一个函数时,在运行被调函数之前,系统需要完成三件事: 1、将所有的实际参数,返回地址等信息传递给被调函数保存 2、为被调函数的局部变量(也包含形参)分配存储空间 3、将控制权转移到被调函数的入口 从主调函数返回被调函数之前,系统要完成三件事 1、保存被调函数的返回结果 2、释放被调函数所占的存储空间 3、依照被调函数保存的返回地址将控制权转移到主调函数 当有多个函数相互调用时,按照 后调先返回 的原则,上述函数之间信息传递和控制转移必须借助 栈 来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中,每当调用一个函数时,就在栈顶分配一个存储区,进行压栈操作,每当一个函数退出时,就释放它的存储区,就进行出栈操作,使运行的函数永远都在栈顶位置, 伪代码分析; # include <stdio.h> void fun ( ) { 语句A ; g ( ) ; 语句B ; } void g ( ) { 语句c; } int main ( ) { fun ( ) ; return 0 ; } 分析; # include <stdio.h> # include <stdlib.h> void f ( ) ; void g ( ) ; void k ( ) ; void f ( ) { printf ( "ffffff\n" ) ; g

【数据结构】线段树

我与影子孤独终老i 提交于 2019-11-28 21:46:58
【数据结构】线段树 这两天被线段树折磨得痛不欲生,大把大把的时间被花在改错上,遂决定将我在这一知识点的学习笔记记录下来,供以后复习使用。 线段树是一种维护 区间信息 的数据结构,可以在O(logn)的时间复杂度内实现单点修改/查询以及区间修改/查询。应用范围包括区间求和,区间求最值等。 这篇笔记以维护区间和的线段树为例。 初始化 线段树的存储 我之前使用的是结构体来存储线段树,如下: struct SegTree { int l,r; //存储每个节点表示的区间 int sum; //存储区间和 int lazy; //存储延迟标记(下文提到,也是个令人抓狂的玩意儿) }segtree[400005]; 但当我写到区间查询时,我把用于存储节点区间的l,r和询问的l,r弄混了(!!!)。 这也是为什么我查错查了一个下午没查出来QAQ 其实,我们可以 直接使用数组存储线段树的数据以及懒惰标记,每个节点表示的区间现场算, 这样也更节省空间。 int tree[400005]; //这里存储的是区间和 int lazy[400005]; 当然如果你的线段树要维护多个东西,还是用结构体方便些,也更加直观。 其实嘛,如果你足够细心,就不会弄出我这种沙雕操作。存下l和r也挺好,可以减小代码常数,节省时间。 建树 众所周知,线段树是一棵完全二叉树,当父节点的编号为x时,它的两个子节点可表示为x<

百万年薪python之路 -- 并发编程之 多线程 二

独自空忆成欢 提交于 2019-11-28 16:25:50
1. 死锁现象与递归锁 进程也有死锁与递归锁,进程的死锁和递归锁与线程的死锁递归锁同理。 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因为争夺资源而造成的一种互相等待的现象,在无外力的作用下,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在相互等待的进程称为死锁进程 # 多个线程多个锁可能会产生死锁 from threading import Thread from threading import Lock import time lock_A = Lock() lock_B = Lock() class MyThread(Thread): def run(self): self.f1() self.f2() def f1(self): lock_A.acquire() print(f'{self.name}拿到A锁') lock_B.acquire() print(f'{self.name}拿到B锁') lock_B.release() lock_A.release() def f2(self): lock_B.acquire() print(f'{self.name}拿到B锁') time.sleep(0.1) lock_A.acquire() print(f'{self.name}拿到A锁') lock_A.release() lock

MySql递归查询实现父子查询

怎甘沉沦 提交于 2019-11-28 10:14:44
父子查询 根据父id查询下面所有子节点数据。 功能需求 我们这里以sec_org(部门表)为例,在一个部门表里面包含org_id(子部门id)、parent_org_id(父部门id)、org_name(子部门名称)等字段,我们要实现通过传入一个部门id,查询出它下面的所有子部门记录的功能。 具体实现 我们可以通过Mysql函数的递归调用来实现。 1.创建函数getChildrenOrg。 CREATE DEFINER=`root`@`%` FUNCTION `getChildrenOrg`(parentId VARCHAR(36)) RETURNS varchar(4000) CHARSET utf8 BEGIN DECLARE oTemp VARCHAR(4000); DECLARE oTempChild VARCHAR(4000); SET oTemp = ''; SET oTempChild = parentId; WHILE oTempChild IS NOT NULL DO SET oTemp = CONCAT(oTemp,',',oTempChild); SELECT GROUP_CONCAT(org_id) INTO oTempChild FROM sec_org WHERE FIND_IN_SET(parent_org_id,oTempChild) > 0;

python函数参数、参数解构、作用域、递归及匿名函数

末鹿安然 提交于 2019-11-28 01:45:56
一、python函数 由若干语句组成的语句块,函数名称,参数列表构成,它是组织代码的最小单元,通过函数完成一定的功能 1、函数的作用 结构化编程对代码的最基本封装,一般按照功能组织一段代码 封装的目的是为了功能复用,减少冗余代码 使代码更加简洁美观,可读易懂 2、函数的分类 内建函数,如:max(),reversed()等 库函数,如math.ceil()等 3、函数的定义和调用 定义 def语句定义函数 函数名就是标识符,命名要求一样 语句块必须缩进,约定4个空格 python的函数若没有return语句,隐式会返回一个None值 定义中的参数列表成为形式参数,只是一种符号表达,简称形参 调用 函数定义只是声明了一个函数,它不会被执行,需要调用 调用方式,就是函数名加上小括号,括号内写参数 调用时写的参数是实际参数,是实实在在的传入的值,简称实参 二、函数参数 参数调用时传入的参数要和定义的个数相匹配(可变参数例外) 位置参数:按照参数定义顺序传入实参fn(1,2) 关键字参数:使用形参的名字来传入实参的方式,如果使用了形参名字,那么传参顺序就可以随意fn(x=1,y=1) 传参:要求位置参数必须在关键字参数之前传入,位置参数是位置对应的; 1、函数参数默认值 参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值 参数非常多的时候