递归算法

算法图解|选择排序和递归

帅比萌擦擦* 提交于 2020-03-03 22:30:30
一:选择排序,O(n2) 选择排序是一种灵巧的算法,但其速度不是很快 代码示例: # 选择排序:O(nxn) # 找出数组中最小的元素 def findsmallest(arr): # 假设小值为arr[0] smallest = arr[0] # 存储最小元素的索引 smallest_index = 0 # O(n) for i in range(1, len(arr)): if arr[i] < smallest: smallest = arr[i] smallest_index = i return smallest_index # 对数组进行选择排序 def selectionSort(arr): newArr = [] # O(nxn) for i in range(len(arr)): smallest_index = findsmallest(arr) # 将该索引的元素添加到newArr newArr.append(arr.pop(smallest_index)) return newArr print(selectionSort([1, 8, 6, 9, 10])) # [1, 6, 8, 9, 10] 二:递归 问题:有个盒子里有盒子,而盒子里的盒子又有盒子。钥匙就在某个盒子中。怎么能找到钥匙。 代码示例: 第一种方法: 详细检查盒子内的东西

复杂计算之多层递归案例

让人想犯罪 __ 提交于 2020-03-03 17:25:21
【摘要】 石油化工行业,经常要构造特殊中间表,以物料、时间、指标名等为参数,查询出对应层级的指标值!由于前端报表模块已经定型,用户不希望再改变,所以只能按照数据库的思路造出这种中间数据集以适用于报表;但事先不能确定维度及其层次的深度,导致 SQL 很难写 (往往用上百行代码才实现一种类型的算法)。总结一下难点:SQL 难以简化、工作量大、维护难、优化难。若能在应用层集成数据计算引擎中间件,使用一致的结构化计算模型,为应用提供统一计算服务;可极大的降低应用与数据库的耦合,后期维护也完全模块化!赶快去乾学院看个究竟吧! 复杂计算之多层递归案例 【下载附件】复杂计算之多层递归案例 来源: oschina 链接: https://my.oschina.net/u/3949403/blog/3186701

算法--递归(6)

旧城冷巷雨未停 提交于 2020-03-03 05:02:53
求n个元素的全排列 理解: n=1 v.pushback(a[n]) print v return for i = 1 to n v.pushback(a[n]) fullArray(v,n-1) v.pop_back() print endl # include <iostream> # include <vector> using namespace std ; void fullArray ( vector < int > & v , int n , vector < int > v0 , int & total ) { if ( n == 0 ) { v . push_back ( v0 [ n ] ) ; size_t size = v . size ( ) ; for ( int i = 0 ; i < size ; ++ i ) { cout << v [ i ] << ends ; } total + = 1 ; cout << endl ; v . pop_back ( ) ; return ; } for ( auto it = v0 . begin ( ) ; it != v0 . end ( ) ; it ++ ) { int temp = it - v0 . begin ( ) ; int temp0 = * it ; v . push_back ( *

PYTHON数据结构与算法学习笔记(六)

[亡魂溺海] 提交于 2020-03-03 02:52:56
目录 树与树算法 树的概念 树的存储与表示 二叉树 二叉树的性质 二叉树的创建 二叉树的遍历 广度优先遍历(层次遍历) 深度优先遍历 树与树算法 树的概念 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点: 1、每个节点有零个或多个子节点; 2、没有父节点的节点称为根节点; 3、每一个非根节点有且只有一个父节点; 4、除了根节点外,每个子节点可以分为多个不相交的子树。 例 : 树的术语 1、 节点的度 :一个节点含有的子树的个数称为该节点的度; 2、 树的度 :一棵树中,最大的节点的度称为树的度; 3、 叶节点或终端节点 :度为零的节点; 4、 父节点 :若一个节点含有子节点,则这个节点称为其子节点的父节点; 5、 子节点 :一个节点含有的子树的根节点称为该节点的子节点; 6、 兄弟节点 :具有相同父节点的节点互称为兄弟节点; 7、 节点的层次 :从根开始定义起,根为第1层,根的子节点为第2层,以此类推; 8、 树的高度或深度 :树中节点的最大层次; 9、 堂兄弟节点 :父节点在同一层的节点互为堂兄弟; 10、 节点的祖先 :从根到该节点所经分支上的所有节点;

JavaScript算法--递归!

*爱你&永不变心* 提交于 2020-03-01 21:54:23
今天给大家讲讲递归 递归其实很好理解 举个例子 比如 借钱 你第一天借了 100块 之后每隔一天你就要多还50元 如果你一直不还 这将是个死循环递归 用代码展示如下 // 简单递归 n代表你第几天还钱 function money(n){ if(n<=1){ return 100; } return 50+money(n-1); } 其中 return money(),就是不断直接的调用自身函数返回的值 直到n<=1的时候 递归返回最终结果 递归就是一个间接或直接的调用自身的函数; 其中return 最为关键 没有返回的值,则无法实现递归 输出则是undefind 来源: CSDN 作者: xbyysj 链接: https://blog.csdn.net/xbyysj/article/details/104599311

递归算法的一般思路总结

跟風遠走 提交于 2020-03-01 21:01:13
** 递归算法 ** 程序直接或间接的调用自身的编程技巧称为递归算法,直接或间接调用自身的函数称为递归函数;它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。 递归问题基本思想:问题层层分析 关键:找出递归定义和递归终止条件 递归定义:使问题向边界条件转化的规则 递归终止条件:所描述问题的最简单的情况,它本身不再使用递归的定义 例: 求1~100的和 递归 fn(n)=n+fn(n-1) 终止条件:fn(1)=1 代码: function fn(n) { If(n<=1) Return 1; Else return n+fn(n-1); } 例: 求最大公因式 (欧几里得算法) 递归: gcd(m,n)=gcd(n,m%n) 终止条件:gcd(m,0)=m 代码: gcd(m,n)//m>n { If(n==0) return(m); else return gcd(n,m m%n); } 例题 求逆波兰表达式 比如说:(2+3) 4 -> * + 2 3 4 比如说 * + 11 12 + 24 35 -> (24+ 35) (11 + 12) = 1357 atof 函数能把char型转换成浮点数 atof():double atof(const char *str ) 思路: 向字符串数组输入,分两种情况,1,是符号,2,是数字

二叉树的非递归遍历与层次遍历

孤人 提交于 2020-03-01 13:50:44
二叉树的递归遍历很好写,也很好理解。但因为是递归程序,不可避免地需要调用系统栈,耗时较长,这里我们来探究一下二叉树的非递归遍历的算法。这种方法需要使用栈这种数据结构,这里关于栈的一些操作函数可以看成伪代码吧,先给出线序、中序、后序遍历的代码即说明。 先序遍历: 1 void PreOrderTraverse(BinTree b) 2 { 3 InitStack(S);///初始化创建栈 4 BinTree p=b;///p为工作指针 5 while(p||!isEmpty(s)) 6 { 7 while(p)///到最左下的孩子 8 { 9 printf(" %c ",p->date);///先序先遍历结点 10 Push(S,p);///入栈 11 p=p->lchild; 12 } 13 if(!isEmpty(s))///在栈不为空的情况下,左孩子为空,弹出该结点,遍历右孩子 14 { 15 p=Pop(s); 16 p=p->rchild; 17 } 18 } 19 } 再给出使用数组模拟的函数 1 void Preorder_n(BiTree bt) /*先序遍历的非递归算法*/ 2 { 3 BiTree stack[MAX],p; 4 int top=0,i; 5 for(i=0; i<MAX; i++) 6 { 7 stack[i]=NULL; /*初始化栈*/ 8

树—最“有套路”的数据结构

ぃ、小莉子 提交于 2020-03-01 09:41:13
前言 标题用“有套路”来形容一种数据结构,似乎有点不尊重的意思。不过,我倒是觉得,一种实用的学科,就是应该产生一点套路,这才能发挥体系化研究的优势,套路就是一种保证: 在不投入更多创造性与努力的情况下,依旧能获得比起随意进行相关操作更好的结果 。一门成熟的学科都应如是,如果研究许久,在学科所研究的许多问题的实践上还不如一些“天赋”“灵感”,那就不得不说这门学科的“伪科学”或者“水分”还是蛮大的了。 言归正传,这篇文章将会是一系列寻找算法与数据结构的文章的开篇,树由于其特性,是递归、分治等等重要算法思想的典型载体,同时套路性较强又具有一定规律和难度,上手后,也可以获得总结其他算法“套路”的必要经验。作为一个训练的开头,还是很合适了。 树的定义与理解 先简要谈谈树的抽象定义:树本质上是一种无向图( 图:由顶点与路径构成的数据结构 ),其中,任意两个顶点之间 有且只有一条 路径。简而言之,树是一种具有特殊性质的图。 树的结构非常直观,而且树的大多数结构具有一个重要性质: 递归 。主要来说,就是树具有某一性质时,往往其子树也具有同样的性质。比如说,一个树如果是二叉搜索树,其子树也必须是二叉搜索树。 根据这样的性质,遇到树的问题,很自然会考虑如何合理使用递归算法,其实质就是:分解为子问题,最后解决基本情况,把复杂的递归过程交给计算机来处理。所以,树类型代码的特点就是简洁(不过换句话说

二叉树递归和非递归遍历

☆樱花仙子☆ 提交于 2020-03-01 03:27:46
二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有前序、中序以及后序三种遍历方法。因为树的定义本身就 是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁。而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现。在三种遍历 中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一点。 一.前序遍历 前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问。 1.递归实现 void preOrder1(BinTree * root) // 递归前序遍历 { if (root != NULL) { cout << root -> data << " " ; preOrder1(root -> lchild); preOrder1(root -> rchild); } } 2.非递归实现 根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下: 对于任一结点P: 1)访问结点P,并将结点P入栈; 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1

permutations全排列的递归算法(c++实现)

风流意气都作罢 提交于 2020-02-29 15:48:12
算法实现原理: 假如abc排列组合会得到abc,acb,bac,bca,cab,cba六种情况。 1)首先将abc的第一个字母放到三者中的第一位得到abc,接着剩下两个字母bc,可以将bc中的第一个字母放到两者中的第一位得到abc,也可以将bc中的第二个字母放到两者中的第一位得到acb。 2)将abc的第二个字母放到三者中的第一位得到bac,接着剩下两个字母ac,可以将ac中的第一个字母放到两者中的第一位得到bac,也可以将ac中的第二个字母放到两者中的第一位得到bca。 … 以此类推。 如果按以上的算法计算acc的排列组合,那么会得到acc,acc,cac,cca,cca,cac六种情况。 那么需要排除其中重复的情况。 对重复的元素序列进行排列组合: 在交换并且进行递归的时候,需要判断交换的两者之间是否有与后者相同的数。比如在计算acc的排列组合时,将acc的第三个字母放到三者中的第一位与将acc的第二个字母放到三者中的第一位是重复的情况,那么则不需要将第三个字母放到第一位进行排列。 代码实现: #include <iostream> using namespace std; void perm(char*, const int, const int); bool isHaveSame(char*, const int, const int); int main() { char