递归

javascript中的递归函数

柔情痞子 提交于 2020-03-12 04:15:20
正常的递归函数如下: 1 function factorial(num){ 2 if(num <= 1){ 3 return 1; 4 }else{ 5 return num * factorial(num-1); 6 } 7 } 这个函数表面看起来还ok,但如果我们执行下面代码就会出错。 1 var jenny = factorial; 2 factorial = null; 3 alert(jenny(4)); // 出错 代码分析: 变量jenny中保存factorial函数的引用,而变量factorial被设置为null, 在调用jenny时,factorial已不再指向函数的引用,所以会出错。 此时我们可改用arguments.callee可以解决此问题。 function factorial(num){ if(num <= 1){ return 1; }else{ return num * arguments.callee(num-1); } } arguments.callee:是一个指向正在执行的函数的指针。 注:在编写递归函数时,使用arguments.callee比直接使用函数名保险,但在严格模式下,使用arguments.callee会导致错误。 所以我们可以使用命名函数表达式来实现相同的效果。 1 var factorial = (function f

DAY2 50.Pow(x,n) (二分查找+递归)

非 Y 不嫁゛ 提交于 2020-03-12 03:51:35
1.题目描述 实现 pow(x, n) ,即计算 x 的 n 次幂函数。 示例 1: 输入: 2.00000, 10 输出: 1024.00000 示例 2: 输入: 2.10000, 3 输出: 9.26100 示例 3: 输入: 2.00000, -2 输出: 0.25000 解释: 2-2 = 1/22 = 1/4 = 0.25 说明: -100.0 < x < 100.0 n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。 2. 思路 1.暴力法:暴力递归,累乘,o(n) 2. 采用二分查找+递归的思想,简化计算复杂度 o(logn) 利用二分查找: 将幂次n/2;计算A = pow(x,n/2)的结果: 若n为偶数,返回 A*A; 若n为奇数,返回A*A*x; 最后再用递归调用完成,递归的边界条件是 n=0,return 1.0; 还有一个注意是: 1.当n为复数时,将转换为正数后再计算并且将 x装换为 1/x; 3.代码实现 class Solution { public: double myPow(double x, int n) { /* 思路: 参考昨天的做法,将计算 平方的平方的平方。。。 1.特殊情况考虑 n<0,用1/n计算; */ long long N = n; if(N<0) { x = 1/x; N = -N; }

数组移动算法

帅比萌擦擦* 提交于 2020-03-12 01:50:57
ASH前段时间贴出了一个问题: 对于有K个元素的数组 int a[K]={....};写一个高效算法将数组内容循环左移m位 比如: int a[6] ={1,2,3,4,5,6} ,循环左移3位得到结果{456123}, 要求: 1不允许另外申请数组空间,但可以申请少许变量 2不允许采用每次左移 这是一个有趣的问题,当时ASH给出了一个很简单的解法: 1、将整个数组倒排; 2、将前k-m个元素和剩下的m个元素分别倒排。 这个算法需要对每个数组元素做两次写操作,所以我当时在考虑,有没有一种方法,只对数组元素进行一次写操作就完成移动? 最直观的想法,就是从第一个元素开始,把它一步移动到最终的目的位置,而该位置原有的元素的值取出,移动到它的新位置。递归进行这个步骤。 首先,我们在数学上很容易理解,这是一个一一对应的映射,绝不会在一个位置上出现两次移动。所以不会出现移动的递归过程中途指向了已经移动过的元素。 那么,这个递归过程唯一的终止条件就是,当前移动的元素,目的位置是移动过程的起始位置。 有兴趣的朋友不妨在纸上推演一下这个过程,并不复杂。多试验几种组合,细心的朋友也许会发现,这个递归过程有时候可以遍历整个数组,有时候则会跳过若干元素。这其中有没有什么规律? 如果按照元素的索引下标标示元素,0到k-1中的任意元素i,会移动到什么位置? 如果i小于m,它会移动到k-m+i,否则

递归:正序、逆序输出一个正整数的各位数字

泪湿孤枕 提交于 2020-03-11 21:58:23
输入一个正整数,用递归的方式输出该数的各位数字,要求正序、逆序都要输出。 嗯这个只是训练递归用的一个小程序。 1 #include <stdio.h> 2 void fun(int n); 3 void fun2(int n); 4 int main(int argc, char *argv[]) 5 { 6 int n; 7 scanf("%d",&n); 8 fun(n); 9 printf("\n"); 10 fun2(n); 11 return 0; 12 } 13 void fun(int n) 14 { 15 int t; 16 if(n==0) 17 { 18 return ; 19 } 20 else 21 { 22 t=n%10; 23 fun(n/10); 24 printf("%d ",t); 25 } 26 } 27 void fun2(int n) 28 { 29 int t; 30 if(n==0) 31 { 32 return ; 33 } 34 else 35 { 36 t=n%10; 37 38 printf("%d ",t); 39 fun2(n/10); 40 } 41 } View Code 来源: https://www.cnblogs.com/huashanqingzhu/p/4476916.html

七大排序及其时间测试

孤街浪徒 提交于 2020-03-11 14:42:49
一、冒泡排序 public class MyBubbleSort { /* 冒泡排序: 时间复杂度:O(n) ~ O(n^2) 最好:顺序 + 标记 最坏: 逆序 稳定性: 稳定 空间复杂度: 常数空间 ---> O(1) */ public static void bubleSort ( int [ ] arr ) { int len = arr . length ; //len是未排序的元素个数 while ( len > 0 ) { //flag:true 已经有序 boolean falg = true ; //一轮冒泡排序 for ( int i = 0 ; i < len - 1 ; i ++ ) { if ( arr [ i ] > arr [ i + 1 ] ) { MySort . swap ( arr , i , i + 1 ) ; falg = false ; } } if ( falg ) { //为真就是有序,有序就跳出 break ; } len -- ; } } } 二、堆排序 public class MyHeapSort { public static void shifDownBig ( int [ ] arr , int parent , int sz ) { int child = parent * 2 + 1 ; while ( child

SpringMVC 使用JSR-303进行校验 @Valid

北慕城南 提交于 2020-03-11 14:19:25
使用注解 一、准备校验时使用的JAR validation-api-1.0.0.GA.jar:JDK的接口; hibernate-validator-4.2.0.Final.jar是对上述接口的实现; log4j、slf4j、slf4j-log4j 二、编写需要校验的bean @NotNull(message="名字不能为空") private String userName; @Max(value=120,message="年龄最大不能查过120") private int age; @Email(message="邮箱格式错误") private String email; 三、校验方法 @RequestMapping("/login") public String testValid(@Valid User user, BindingResult result){ if (result.hasErrors()){ List<ObjectError> errorList = result.getAllErrors(); for(ObjectError error : errorList){ System.out.println(error.getDefaultMessage()); } } return "test"; } 备注:这里一个

快速排序算法的递归与非递归

◇◆丶佛笑我妖孽 提交于 2020-03-11 12:59:18
//quick sort void quicksort (int array[], int low, int high){ if(low<high){ int index = getindex(array,low,high); quicksort(array,index+1,high); quicksort(array,0,high); } } int getindex(int array[],int low, int high){ int temp = array[low]; while (low<high){ if(array[high] >temp ){ high --; } array[low] = array[high]; if(array[low]<temp){ low++; } array[high] = array[low]; } array[low] =temp; return low; } //非递归的形式来实现快排 void quichsortnorecusive(int array[],int low,int high[]){ stack<int> s; s.push(low); s.push(high); while(!s.empty()){ int h = s.top(); s.pop(); int l = s.top(); s.pop(); int

递归的四条基本法则

房东的猫 提交于 2020-03-11 10:44:16
在编写递归程序时,关键是要牢记递归的四条基本法则: 1、基准情形。必须总有某些基准情形是不用递归就能求解的。 2、不断推进。对于那些需要递归求解的情形,递归调用必须总能朝着基准情形的方向推进。 3、设计法则。假设所有的递归调用都能运行。 4、合成效益法则。在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。 来源: CSDN 作者: ThetaQing 链接: https://blog.csdn.net/Thera_qing/article/details/104790132

02 树的各种遍历(递归与非递归的先中后序遍历,层次遍历)

旧时模样 提交于 2020-03-11 09:51:03
二叉树的前中后遍历,递归与非递归 struct TreeNode { int val ; TreeNode * left ; TreeNode * right ; TreeNode ( int x ) : val ( x ) , left ( NULL ) , right ( NULL ) { } } ; 递归 先序遍历: void PreOrderTraversal ( TreeNode * root ) { if ( ! root ) { return ; } cout << root - > val << " " ; PreOrderTraversal ( root - > left ) ; PreOrderTraversal ( root - > right ) ; } 中序遍历 void InOrderTraversal ( TreeNode * root ) { if ( ! root ) { return ; } InOrderTraversal ( root - > left ) ; cout << root - > val << " " ; InOrderTraversal ( root - > right ) ; } 后序遍历 void PostOrderTraversal ( TreeNode * root ) { if ( ! root ) { return

递归

喜你入骨 提交于 2020-03-11 03:20:25
什么问题可以用递归? 当前问题可以进行拆分,拆分为子问题。子问题的本质和父问题是一样的,解决了子问题,父问题也就迎刃而解。同时子问题可以继续向下分解。 例如:数组排序问题 分解为数组左边部分排序和又边部分排序 找数组最大数问题 找数组左边最大数和数组右边最大数,然后返回最大的那一个 求 n 的阶乘 等价于求(n-1)的阶乘再乘以n n-1的阶乘等于n-2的阶乘再乘以n-1 递归行为 递归行为在程序执行时,相当于系统帮程序员进行压栈出栈的行为,在压栈的时候不仅会将要执行的函数、变量等压入栈中,同时还会记录当前执行到程序的哪一行。 递归的时间复杂度估算 master公式的使用 T(N) = a*T(N/b) + O(N^d) log(b,a) > d -> 复杂度为O(N^log(b,a)) log(b,a) = d -> 复杂度为O(N^d * logN) log(b,a) < d -> 复杂度为O(N^d) 例如:找数组最大值 int Maxnum ( vector < int > & obj , int left , int right ) { if ( left == right ) return obj [ left ] ; int mid = ( left + right ) / 2 ; int left_max = Maxnum ( obj , left , mid )