递归函数
记录一下递归函数
递归函数 分为两部分:
1.递归点 --重复执行的部分
2.出口 --函数的出口.
设计:递归函数用if-else来完成
/*阶乘的例子*/
int func(int n) { if( n > 1 )
{ return n* func(n-1); //递归点 }else
{ return 1; //出口 } }
如果输入的参数 n > 0,就执行第一个判断体.
return n* func( n - 1);
假设n = 3,
第一次 执行 return 3* func(2);
第二次 执行 return 2* func(1);
第三次就是出口 执行else return 1;
return到上级调用者.
从第一次来看y = 3 * 变量1;
变量1 = 2 * 变量2;
变量2 = 1;
综上 y = 3 * 2 * 1;
再看一个复杂一些的例子-list中的递归函数.
目的:我需要遍历到链表的末尾
设计方案:递归
typedef struct _link_t link_t; struct _link_t { //链表的结构体 node_t *np; //表头指针 int length; //表的长度 }; node_t *link_to_end(node_t *nt){ //设计一个函数,返回值是node_t的指针(节点指针),参数也是一个节点指针,第一次执行的应该是入口指针 if(nt -> p){ //如果 节点指针指向的下一个节点 存在的话,判断成立,注意nt->p 的意义是下一个节点的地址 return link_to_end(nt ->p); //如果上一句成立,就进入这里,返回不返回不重要,重要的是,将下一个节点的地址,作为新的参数,然后重新寻找属于它的下一个节点. }else{ return nt; //如果遍历到最后,已经没有下一个节点了,就把当前节点的地址返回给最上层调用者. } }
通过对比两个例子我们会发现
例子1是对每一个递归值都需要
例子2是只关注最后一个出口值
所以递归函数的设计由使用者决定.另外,递归太深,似乎会让程序跑比较吃力吧...总觉得...