判断一个M*N的国际象棋马跳图是否有汉密顿回路

来源:互联网 发布:linux关闭服务器命令 编辑:程序博客网 时间:2024/05/09 05:59

                 最近上了算法课,写了一个判断M*N的马跳图中,是否存在汉密顿回路。用的是完全遍历的方法,这里没有使用递归的方法,一直遍历图中的路径节点,直到找到一条满足条件汉密顿回路则停止,当然,这样的算法效率比较低,特别是图中没有汉密顿回路时,要遍历所有可能的路径。

希望与大家共同学习,共同进步

后续会写一个用分支限界来判定的方法。。。敬请期待!

#include<stdio.h>#define M  6                             //行数#define N  6                            //列数int islegal(int x, int y);void main(void){int flag[M][N];                          //标注是否走过int route[M*N][8];                       //标注每个方向的路径是否可走,0为不可走,1为可走//标记每一步的前一步的行和列int fromcol[M*N]={0};                          int fromrow[M*N]={0};int direct[][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}}; //每步可以走的八个方向    int curcol=-1;                       //当前行int currow=-1;                       //当前列int nextcol=-1;                      //下一行int nextrow=-1;                      //下一列  // 初始化flagint i,j;for(i=0;i<M;i++){for(j=0;j<N;j++){flag[i][j]=0;}}//初始化routeint k;int pos;                              //当前在数组中的位置for(curcol=0; curcol<M; curcol++){for(currow=0; currow<N; currow++){pos=curcol*N+currow;for(k=0; k<8; k++){nextcol=curcol+direct[k][0];nextrow=currow+direct[k][1];if(islegal(nextcol,nextrow)){route[pos][k]=1;}else{route[pos][k]=0;}}}} //回溯遍历寻找路径curcol=0;currow=0;pos=0;int num=1;while(num<=M*N)                                                 //当又回到原点时结束{for(i=0;i<8;i++)                                 //寻找下一个合适的步{nextcol=curcol+direct[i][0];nextrow=currow+direct[i][1];if(nextcol==0 && nextrow==0 && num==M*N){num++;      //为了退出循环break;}if(islegal(nextcol,nextrow) && flag[nextcol][nextrow]==0){if(route[pos][i]){flag[curcol][currow]=1;route[pos][i]=0;                          //防止回溯时走已走过的路curcol=nextcol;currow=nextrow; pos=curcol*N+currow;fromcol[pos]=curcol-direct[i][0];        //保存前一个点的位置fromrow[pos]=currow-direct[i][1];num++;break;}}}if(i==8)                                           //没有找到合适的步,进行回溯{if(flag[curcol][currow]==1){flag[curcol][currow]=0;}pos=curcol*N+currow;for(j=0; j<8; j++)               //恢复退出的节点{if(islegal(curcol+direct[j][0],currow+direct[j][1]) && route[pos][j]==0){route[pos][j]=1;}}curcol=fromcol[pos];currow=fromrow[pos];pos=curcol*N+currow; num--;if(num==0)break;}}printf("%d\n",num);printf("%d,%d",curcol,currow);if(num==0){printf("无  汉密顿回路\n");}else if(num==M*N+1){printf("有  汉密顿回路\n");}}// 所在位置合法是返回值为1;否则返回0int islegal(int x, int y){if((x>=0 && x<M) && (y>=0 && y<N))return 1;else{return 0;}}
原创粉丝点击