求解递归算法

递归

什么是递归

  1. 递归既是手段,又是计算思维方式

  2. 求解方法的递归性:方法是旧的,问题是新的

  3. 涉及的算法策略

    1. 蛮力法:是一种简单直接地解决问题的方法,常常直接基于问题的描述

    2. 分治法:把一个问题分成两个或无数多个相似的子问题,再把子问题分成更小的子问题,

      直到可以直接求解,原问题的解即子问题解的合并

    3. 回溯法:一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”

    4. 动态规划法:运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题最短路径问题和复杂系统可靠性问题等中取得了显著的效果。

  4. 递归算法设计的框架

    1. 递归模型---->递归算法
    2. 求递归模型的步骤
      1. 对原问题f(s)进行分析,称为大问题,假设出合理的小问题f(s)’
      2. 假设f(s)‘是可解的,在此基础上确定f(s)的解,即给出f(s)与f(s’)之间的关系,即递归体
      3. 确定一个特殊情况如(f(1),f(0))的解,即递归出口
  5. 例求解最大数

        int fmax(int a[],int i){
            if (i==1){
                return a[0];
            }else{
                return Math.max(fmax(a,i-1),a[i-1]);
            }
        }
    

递归算法设计

  1. 常见的递归数据

    • 线性表
  2. 不带头结点的单链表的相关递归算法设计

    1. 为什么要不带头节点,因为带头的话,分割成无数个小问题时,小问题也要带头结点
    2. 对于空单链表的数据节点个数为0,f(L)=0,l=null
    3. 对于非空链表,f(L)=f(L–>next)+1
    int count(LInkNOde *L){
        if(L==NUll)
            return 0;
        else
            return count(L->next)+1;
    }
    

    4.显示所有节点值

    //正向显示
    void traverse(LinkNode *L){
        if(L==null) return ;
        printf("%d",L->data);
        traverSer(L->next);
    }
    //反向
    void traverseR(LinkNode *L){
        if(L==null) return;
        traverSer(L->next);
        printf("%d",L->data);
    }
    
    1. 假设二叉树采用二叉链表结构,设计一个递归算法由二叉树bt复制产生另一颗二叉树。

      1. f(bt,bt1)=bt1=null

      2. f(bt,bt1)=f(bt->1child,bt1->1child);f(bt->rchild,bt1->rchild)

      3. void CopyBTree(BTNOde,*bt,BTNode *&bt1){
            if(bt==null)
                bt1=null;
            else{
                bt1=(BTNode *)malloc(sizeof(BTNode));
                bt1->data=bt->data;
                CopyBTree(bt->lchild,bt1->lchild);
                CopyBtree(bt->rchild,bt1->rchild);
            }
        }
        

​ 4. 用vector 向量path存放从根节点到x节点的正向路径

  1. 求解n的阶乘,0的个数

    //求解原理:因式中5的个数
    int ZEronum(int n){
        if(n>0&&n<5)
            return 0;
        else{
            int k=n/5;
            return k+Zeronum(k);
        }
    }
    
  2. 求解迷宫图

    #include<studio.h>
    #define max_size=8
    int h[4]={0,1,0,-1};//水平偏移量
    int v[4]={-1,0,1,0}//垂直偏移量
    char maze[max_size][max_size]={
        {'x','x','x','x','x','x','x','x'},
        {'0','0','0','0','x','x','x','x'},
        {'x','x','x','0','x','x','x','x'},
        {'x','x','x','0','x','x','x','x'},
        {'x','x','x','0','x','x','x','x'},
        {'x','x','x','0','0','0','x','x'},
        {'x','x','x','x','x','0','x','x'},
        {'x','x','x','x','x','0','0','0'}
    };
    void FindPath(int x,int y){
        //8*8迷宫
        if(x==max_size-1&&y==max_size-1){
            Maze[max_size-1][max_size-1]='';
            for(int i=0;i<max_size;i++){
                printf(" ");
                for(int j=0;j<max_size;j++)
                    printf("%c",maze[i][j]);
                printf("\n");
            }
            return;
        }else if(x>=0&&y>=0&&y<max_size &&x<max_size&&maze[x][y]=='0')//若(x,y)方块可走
        {
            //试探每一个方位
            for(int k=0;k<4;k++){
                maze[x][y]=''; //将该方块设置为空字符
                FindPath(x+v[k],y+H[k]);//查找(x,y)周围的每一个相邻方块
                maze[x][y]='0';//找到路径,恢复(x,y)
            }
        }
    }
    
  3. 求解n皇后问题

    #define N 20
    int q[N];
    int count=0;
    void dispasolution(int n){
        printf("第%d个解:",++count);
        for(int i=1;i<=n;i++)
            printf("(%d,%d)",i,q[i]);
        printf("\n");
    }
    //是否在同一条对角线上,|q[k]-j|==|i-k|
    //同一列 q[k]==j
    //同一行 k=x
    //冲突条件 (q[k]==j)||(abs(q[k]-j)==abs(i-k))
    bool place(int i,int j){
    if(i==1) return true;
        int k=1;
        while(k<i)
        {
            if((q[k]==j)||(abs(q[k]-j)==abs(i-k)))
                return fales;
            k++;
        }
        return true;
    }
    void queen(int i,int n){
        if(i>n)
            dispasoulition(n);
        else{
            for(int j=1;i<=n;j++)
                if(place(i,j)){
                    q[i]=j;
                    queen(i+1,n);
                }
        }
    }
    void main(){
        int n;
        queen(1,n);//放置1~n个皇后
    }
    
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值