• 数据--第20课-递归的应用实战二


    第20课-递归的应用实战二

    1. 递归与回溯

    (1)递归在程序设计中也常用于需要回溯算法的场合。

    (2)回溯算法的基本思想。

    ① 从问题的某一种状态出发,搜索可以到达的所有状态。

    ② 当某个状态到达后,可向前回退,并继续搜索其它可达状态 ,并继续搜索其它可达状态。

    ③ 当所有状态都到达后,回溯算法结束。

    (3)程序设计中可利用函数的活动对象保存回溯算法的状态数据,因此可以利用递归完成回溯算法

    2. 八皇后问题

    在一个8×8国际象棋盘上,有8个皇后,每个皇后占一格;要求皇后间不会出现相互“攻击”的现象,即不 能有两个皇后处在同一行、同一列或同一对角线上。

    3. 解决方案--算法思路

    (1)初始化:i = 1

    (2)初始化:j = 1

    (3)从第i行开始,恢复j的当前值,判断第j个位置

    a. 位置 j可放入皇后:标记位置(i, j),i++ 转步骤2

    b. 位置j不可放入皇后:j++转步骤a

    c. 当j>8时,i--,转步骤3

    4. 结束:

     第8 第8行有位置可放入皇后

    4. 程序

    #include <stdio.h>

    #define N 8

    typedef struct _tag_Pos

    {

        int ios;

        int jos;

    } Pos;

    static char board[N+2][N+2];

    static Pos pos[] = { {-1, -1}, {-1, 0}, {-1, 1} };

    static int count = 0;

    void init()

    {

        int i = 0;

        int j = 0;

       

        for(i=0; i<N+2; i++)

        {

            board[0][i] = '#';

            board[N+1][i] = '#';

            board[i][0] = '#';

            board[i][N+1] = '#';

        }

       

        for(i=1; i<=N; i++)

        {

            for(j=1; j<=N; j++)

            {

                board[i][j] = ' ';

            }

        }

    }

    void display()

    {

        int i = 0;

        int j = 1;

       

        for(i=0; i<N+2; i++)

        {

            for(j=0; j<N+2; j++)

            {

                printf("%c", board[i][j]);

            }

           

            printf(" ");

        }

    }

    int check(int i, int j)

    {

        int ret = 1;

        int p = 0;

       

        for(p=0; p < 3; p++)

        {

            int ni = i;

            int nj = j;

           

            while( ret && (board[ni][nj] != '#') )

            {

                ni = ni + pos[p].ios;

                nj = nj + pos[p].jos;

               

                ret = ret && (board[ni][nj] != '*');

            }

        }

       

        return ret;

    }

    void find(int i)

    {

        int j = 0;

       

        if( i > N )

        {

            count++;

           

            printf("Solution: %d ", count);

           

            display();

           

            getchar();

        }

        else

        {

            for(j=1; j<=N; j++)

            {

                if( check(i, j) )

                {

                                       

                    board[i][j] = '*';

                   

                    find(i+1);

                   

                    board[i][j] = ' ';

                }

            }

        }

    }

    int main()

    {

        init();

        find(1);

       

        return 0;

    }

    小结

    l  回溯算法是递归应用的重要场合。

    l  利用函数调用的活动对象可以保存回溯算法中重要的变量信息。

  • 相关阅读:
    Houdini 快捷键使用说明
    在Houdini中创建自定义的Python函数
    用正则表达式校验QQ号码
    [Chatter] 看小说「数字风暴」有感
    [.NET] 当用System.Messaging.MessageQueue.Send传送数据遇到InvalidCastException、NullReferenceException
    [Visual Studio] 方案总管中,自定义档案与档案之间的父子关系
    [.NET] 子对象方法的参数,参考子对象型别做为输入型别
    [Chatter] 引用新技术的考虑
    [Architecture Pattern] Inversion of Logging
    [Architecture Design] DI Thread Tips
  • 原文地址:https://www.cnblogs.com/free-1122/p/11322815.html
Copyright © 2020-2023  润新知