我的递归总结

来源:互联网 发布:mac蓝光播放软件 编辑:程序博客网 时间:2024/06/05 15:31

     

          最近学到了数据结构的广义表 ,发现广义表 定义递归 , 获取深度递归 , 总之基于广义表上面的操作 , 只有长度的获取没有使用到递归。。。。

          才发现递归看别人写好理解 , 自己设计就会存在很多问题 .

          做了一些递归题目,以及对比以前的递归题目  , 下面谈谈 , 个人对递归算法的见解。


下面对递归进行如下分类 :

     ( 1 ) 带有回溯的递归 :

              特点 : 递归函数本身具有返回值 , 而且基本不是在当前函数一次调用函数本身的递归 。

                          会素操作是针对当前递归层次的操作 : 可以是返回值,当然也可以是别的操作;

              典型例子 :

                            二叉树的创建

                           二叉树 某一 结点的检索 。

                           二叉树的销毁

                          广义表的递归创建

                          广义表的深度的测量

                          广义表的销毁 

                          使用递归的迷宫算法

                          

                          

              想法 : 想这样具有多分支探索和构建 ,  完全可以只关注 问题的一个最小子问题 .。

                         比如二叉树的创建 , 就关注当前结点以及他的左儿子 和 右儿子就可以 了 ,但是需要返回当前结点的操作,来当做回溯 : 算法步骤如下

                 

TNode * CreateTree(TNode * node){      if(某种情况   : 递归出口){  //叶子结点的后继节点为空          return NULL;               }      //创建左子树     node->lChild = CreateNode(node->lChild);     node->rChild = CreateNode(node->rChild);          //回溯操作     return node;}  


 (2 )有递推关系式的递归 :

          此类递归可以明显的找出递推关系式 :

          典型例子有 :

                      阶乘的递归形式 :  f(n) =   1               n=1;

                                                            n*f(n-1)      n>1;

                      斐波拉契数列递归 :  f(n) = 1      n = 1;

                                                            = 1     n  = 2;

                                                            =  f(n-1) + f(n-2);

                      猴子偷桃 :       f(n) =      return  结果    n=1 时

                                                            f(n-1)/2+1;

                   


 ( 3 ) 多分支不定情况 : 

          相比较第(1)种 , 此类情况也许更贴近 博弈  , 概率 , 以及排列组合的情况 :

                              最近做的题目 : 取石子的问题 :


 (4)  排列组合的问题 :

               排列 :  

                         交换  全排列  : 代码如下 :

void perm(int * a,int start,int end){   if(start == end){      输出数组a   }else{       int i;     for(i=0;i<end;i++){         swap(a,start,i);         perm(a,i,end);         swap(a,start,i);     }  } } 
                    

                       有序全排列 :

int a[MAX]={0};   //注意的MAX == endvoid perm(int *a,int start,int end){    if(start == end){      //输出全排列的信息    }else{      //开始全排列      int i;      for(i=0;i<end;i++){        if(!a[i]){              a[i] = i;              perm(a,start+1,end);              a[i] = 0;         }             }    }} 


         

              组合 : 从个数据中选取 2 个数据有多少种情况

                         可以分解成以下情况 : (1) 当前抽取的人不在当前2 个人当中

                                                          (2) 当前抽取的人 在当前抽取的两个人当中

                   


       代码如下 :

 

                          

                         

                                                  

void Comm(int n,int k){  if(k==0) return 1;  if(k==n) return 1;  return Comm(n-1,k-1)+Comm(n-1,k);}



在做到题目 , 再往里面加吧。。。。

原创粉丝点击