• 马踏棋盘代码分析


    马踏棋盘代码分析

                             (因为最近数据结构讲到图和网,听是能听懂,可是一到代码上,就发现问题很多,因此将马踏棋盘的代码拿出来分析下,貌似有些不对头,其实呢是因为不想写其余的作业,所以找个借口)

    说到马踏棋盘,这样说,就是一个8*8的棋盘,指定一个位置,让马走日字,将棋盘上的点全部走完。

       先说说思路:首先指定位置,在这个位置的基础上走一个位置,然后再在这个基础上走日字,现在面临一个问题,要是走着走着,突然有一次,就那么的卡住在那里了,怎么走都不行,可是全局看下,会发现,还有空点没有踏到,那么怎么办?看来这条路不通了,那就得重新的找一条路,怎么从一条路到另一条路呢?那就是退回,要退回,必须有退回的路,因此呢,要有标记,不然,就找不到退回的路了,退回到另一条路,然后继续探索,走日字,卡住了就退,哦,这里要记得将原来路也记一下,不然,你有可能重走这条不归路。就这样不停的走,不停地退,最终就会找到一条你想找的路。大体思路就是这样的,思路简单,用代码写起来,一定要逻辑清楚,我就是经常混在这种情况下,出不来进不去。

       恩,来看代码:

       声明:是MAXSIZE是100

      先定义一个8*8的棋盘:

       int board[8][8];          

      棋盘要进行初始化:N是8

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

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

             board[i][j]=0;

    那么现在要输入马踏的位置,这就需要用户自己输入:记得要进行完善,要是用户输入的坐标不正确,要提示重新输入:

    while(1)

    printf("Please enter the location of the first step of the horse(1<=x<=8 and 1<=y<=8) ");

    printf("Input x = "); 

    scanf("%d",&x);         //输入起始位置的横坐标

    printf("Input y = "); 

    scanf("%d",&y);         //输入起始位置的纵坐标

    if(x>=1&&x<=8&&y>=1&&y<=8)

    break;  //若输入的坐标超出所给棋盘的允许范围则跳出循环

    printf("Your input is worng!!! ");

    }

    当输入正确后,就应该将值传进去:调用起始坐标函数

     InitLocation(x-1,y-1)

    这里就要用到栈:利用栈的特点,来记录走过的路

    栈的定义:

    struct Stack

    {                  

    int i;                  //行坐标

    int j;                  //列坐标

             int director;           //存储方向

    }stack[MAXSIZE]; 

    同时定义了一个栈指针:用来记录栈的元素进入和删除,相当于计数器

    int top=-1;              

    然后是InitLocation函数

    void InitLocation(int xi,int yi)

                              top++;                  //栈指针指向第一个栈的底层

                                stack[top].i=xi;           //将起始位置的横坐标进栈

                                stack[top].j=yi;           //将起始位置的纵坐标进栈

                                stack[top].director=-1;     //将起始位置的尝试方向赋初值

                                board[xi][yi]=top+1;       //标记棋盘

                                if(TryPath(xi,yi))            //调用马儿探寻函数,如果马儿探寻整个棋盘返回1否则返回0

                                Display();         //输出马儿的行走路径

                                else                    

                                 printf("sorry ,There is no solution");     

    }

    上面有两个函数:TryPath(x,y)和Display();

     尝试路径:

    int Htry1[8]={1,-1,-2,2,2,1,-1,-2}; 

    //存储马各个出口位置相对当前位置行下标的增量数组

    int Htry2[8]={2,-2,1,1,-1,-2,2,-1};                 

    //存储马各个出口位置相对当前位置列下标的增量数组

    int TryPath(int i,int j)

    int find,director,number,min;        

    int i1,j1,h,k,s;              //定义几个临时变量

    int a[8],b1[8],b2[8],d[8];     //定义几个临时数组

    while(top>-1)                 //栈不空时循环

    for(h=0;h<8;h++)    //用数组a[8]记录当前位置的下一个位置的可行路径的条数

    number=0; 

    i=stack[top].i+Htry1[h];

    j=stack[top].j+Htry2[h];

    b1[h]=i;

    b2[h]=j; 

    if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8)    //如果找到下一位置

    {

    for(k=0;k<8;k++)

    i1=b1[h]+Htry1[k];

                   j1=b2[h]+Htry2[k]; 

               if(board[i1][j1]==0&&i1>=0&&i1<8&&j1>=0&&j1<8) //如果找到下一位置   

    number++;              //记录条数

        a[h]=number;                   //将条数存入数组a[8]中

    }

    for(h=0;h<8;h++)     //根据可行路径条数小到大按下表排序放入数组d[8]中

    {  

    min=9; 

    for(k=0;k<8;k++)

    if(min>a[k]) 

    min=a[k]; 

    d[h]=k;    //将下表存入数组d[8]中

             s=k;

        a[s]=9;

          director=stack[top].director;     

    if(top>=63)                 //如果走完整个棋盘返回

    return (1); 

    find=0;                     //表示没有找到下一个位置

    for(h=director+1;h<8;h++)   //向八个方向进行探寻

    i=stack[top].i+Htry1[d[h]];

        j=stack[top].j+Htry2[d[h]]; 

    if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置

    find=1;       //表示找到下一个位置

    break;

    }

    if(find==1)          //如果找到下一个位置进栈

    stack[top].director=director; //存储栈结点的方向

    top++;                      //栈指针前移进栈

    stack[top].i=i;

    stack[top].j=j; 

    stack[top].director=-1;    //重新初始化下一栈结点的尝试方向

    board[i][j]=top+1;         //标记棋盘

    else                           //否则退栈

    {  

    board[stack[top].i][stack[top].j]=0;  //清除棋盘的标记

    top--;                     //栈指针前移退栈

    }

    return (0);   

    }

    打印棋盘:board[i][j]里已经记录了走的次序,只需输出即可

    void Display()

        int i,j; 

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

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

    printf(" %d  ",board[i][j]);  //输出马儿在棋盘上走过的路径

    printf(" ");

    printf(" ");

    }

    恩恩 结束了,哦在来个运行结果截图:

                by:暖暖

               20141124

  • 相关阅读:
    LeetCode 67 Add Binary(二进制相加)(*)
    从头认识Spring-3.1 简单的AOP日志实现-某方法之前的前后记录日志
    Registration system
    BZOJ 1055 HAOI2008 玩具取名 动态规划
    9.Laravel5学习笔记:在laravel中注冊自己的服务到容器中
    B-Tree 索引和 Hash 索引的对照
    负载均衡之基于DNS负载
    Eclipse中git插件导入远程库和上传项目源代码到远程库
    Android开发艺术-第二章 IPC 机制
    一天教你入门struts2
  • 原文地址:https://www.cnblogs.com/2714585551summer/p/4119735.html
Copyright © 2020-2023  润新知