1、 什么是递归
成都创新互联是一家集网站建设,大东企业网站建设,大东品牌网站建设,网站定制,大东网站建设报价,网络营销,网络优化,大东网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
在程序中,所谓的递归,就是函数自己直接或间接调用自己
1.1 直接调用自己
- function f() {
- console.log( 1 );
- f();
- }
1.2 间接调用自己
- function f1(){
- f2();
- }
- function f2() {
- f1();
- }
就递归而言,最重要的是跳出结构,因为只有跳出结构才可以有结果。
1.3 所谓的递归就是化归思想
递归的调用,写递归函数,最终还是要转换为自己这个函数
加入有一个函数f,如果他是递归函数的话,也就是说函数体内的问题还是转化为 f 的形式。
递归思想就是将一个问题转换为一个已解决的问题来实现
例子:1,2,3,4,...,100,累加的结果
- var res = foo( 100 );
- var res = foo( 99 ) + 100;
- function foo ( n ) {
- return n + foo( n -1 );
- }
- function foo( n ) {
- return ( n ==1 ) return 1;
- return n + foo( n -1 );
- }
2、 递归求值举例
2.1 等差数列1
数列:求 1, 3, 5, 7, 9, ... 第 n 项的结果与前 n 项和. 序号从 0 开始
求第 n 项的值
- function fn( n ) {
- return fn( n-1 ) + 2;
- }
求 n -> n-1
求 n-1 -> n-2
...
求 1 -> 0
求 第 0 项, 就是 1
- function fn( n ) {
- if ( n == 0 ) return 1;
- return fn( n-1 ) + 2;
- }
前N项的和
- function sum( n ) {
- return fn( n ) + sum( n - 1 );
- }
n == 1 结果为1
- function sum( n ) {
- if ( n == 0 ) return 1;
- return fn( n ) + sum( n - 1 );
- }
2.2 等差数列2
数列:2, 4, 6, 8, 10 第 n 项与 前 n 项和
第n项
- function fn( n ) {
- if ( n == 0 ) return 2;
- return fn( n-1 ) + 2;
- }
前n项和
- function sum( n ) {
- if ( n == 0 ) return 2;
- return sum( n - 1 ) + fn( n );
- }
2.3 差分数列
数列: 1, 1, 2, 4, 7, 11, 16, … 求 第 n 项, 求前 n 项和.
求第 n 项,从0开始
第 0 项和第 1 项,相差0 => fn( 0 ) + 0 = fn( 1 )
第 1 项和第 2 项,相差1 => fn( 1 ) + 1 = fn( 2 )
第 2 项和第 3 项,相差2 => fn( 1 ) + 2 = fn( 2 )
...
第 n-1 项和第 n 项,相差n-1 => fn( n -1 ) + n -1 = fn( n )
- function fn ( n ){
- if( n == 0 ) return 1;
- return fn( n -1 ) + n - 1;
- }
如果从 1 开始表示, 那么第 n 项为
第 1 项和第 2 项,相差0 => fn( 1 ) + 0 = fn( 2 )
第 2 项和第 3 项,相差1 => fn( 2 ) + 1 = fn( 3 )
第 3 项和第 4 项,相差2 => fn( 3 ) + 2 = fn( 4 )
...
第 n-1 项和第第 n 项,相差 n - 1 => fn( n -1 ) + n -2 = fn( n )
前n项和
- function sum( n ) {
- if ( n == 1 ) return 1;
- return sum( n - 1 ) + fn( n );
- }
2.4 斐波那契数列
这是最常见,面试***问的知识之一,斐波那契数列为:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …
求其第 n 项
递推关系 fn(n) == fn( n- 1) + fn( n - 2),于是,递归函数为
- function fib ( n ) {
- if( n ==0 || n == 1 ) return 1;
- return fib( n -1 ) + fib( n -2 );
- }
3、高级递归
3.1 阶乘
计算阶乘是递归程序设计的一个经典示例。阶乘是一个运算,计算某个数的阶乘就是用那个数去乘包括 1 在内的所有比它小的数。例如,factorial(5) 等价于 5*4*3*2*1,而 factorial(3) 等价于 3*2*1。
5! 就是 1 * 2 * 3 * 4 * 5. 0 的阶乘是1, 阶乘 从 1 开始。
求 n 的阶乘
- function foo( n ){
- if( n == 1 ) return 1;
- return foo( n -1 ) * n;
- }
- console.log(foo(5)); //120
跟前面的1到100的求和的递归函数很相似,只是一个变种
3.2 求幂
求幂就是求 某一个数 几次方
2*2 2 的 平方, 2 的 2 次方
求 n 的 m 次方
最终要得到一个函数 power( n, m )
n 的 m 次方就是 m 个 n 相乘 即 n 乘以 (m-1) 个 n 相乘
- function power( n, m ) {
- if( m == 1 ) return n;
- return power( n , m -1 ) * n;
- }
- console.log(power(2,3)); //8
4、递归深拷贝
如果要实现深拷贝,那么就需要考虑将对象的属性,与属性的属性,....都拷贝过来
4.1 简单实现
如果要实现:
- function clone( o1,o2 ){
- for( var k in o2 ){
- o1[ k ] = o2[ k ];
- }
- }
假设方法已经实现,问一下,如果o2[ k ] 是对象
继续使用这个方法
因此需要考虑的是o2[ k ] 如果是引用类型,再使用一次clone()函数
如果o2[ k ] 不是引用类型,那么就直接赋值
- function clone( o1, o2 ) {
- for ( var k in o2 ) {
- if ( typeof o2[ k ] == 'object' ) {
- o1[ k ] = {};
- clone( o1[ k ] , o2[ k ] );
- } else {
- o1[ k ] = o2[ k ];
- }
- }
- }
- var person1 = {
- name: '张三',
- children: [
- { name: '张一' },
- { name: '张二' },
- { name: '王三' }
- ]
- };
- var person2 = {};
- clone( person2, person1 );
4.2 复杂实现 clone( o ) -> newObj
- function clone( o ) {
- var temp = {};
- for( var k in o ) {
- if( typeof o[ k ] == 'object' ){
- temp[ k ] = clone( o[ k ] );
- } else {
- temp[ k ] = o[ k ];
- }
- }
- return temp;
- }
- var person1 = {
- name: '张三',
- children: [
- { name: '张一' },
- { name: '张二' },
- { name: '王三' }
- ]
- };
- var person2 = clone(person1);
- // 修改一个看另一个是否也修改
- person2.name = '李四';
- person2.children[ 0 ].name = '王小虎';
- person2.children[ 1 ].name = '张大虎';
- person2.children[ 2 ].name = '李长虎';
4.3 递归实现getElementsByClassName方法
有如下DIV结构:
1 2 3 4 5 6 7 8
- function byClass( node, className, list ){
- var nodes = node.childNodes;
- for( var i=0; i
- if( nodes[ i ].className == className ){
- list.push( nodes[ i ] );
- }
- if( nodes[ i ].childNodes.length > 0 ){
- byClass( nodes[ i ], className, list );
- }
- }
- }
- var arr = [];
- byClass( document.body, 'c', arr );
- console.log(arr);
本文名称:进阶JavaScript之玩转递归与数列
网站路径:http://www.mswzjz.cn/qtweb/news20/19370.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能