三木社区

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 320|回复: 0
打印 上一主题 下一主题

C语言数据结构-algo3-11.c

[复制链接]

1562

主题

1564

帖子

4904

积分

博士

Rank: 8Rank: 8

积分
4904
跳转到指定楼层
楼主
发表于 2017-9-1 08:26:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /* algo3-11.c 利用非循环顺序队列采用广度搜索法求解迷宫问题(一条路径) */
  2. #include"c1.h"
  3. #define M 5 /* 迷宫行数(包括外墙) */
  4. #define N 5 /* 迷宫列数(包括外墙) */
  5. #define D 8 /* 移动方向数,只能取4和8。(8个,可斜行;4个,只可直走) */

  6. typedef struct /* 定义队列元素和栈元素为同类型的结构体 */
  7. {
  8.    int x,y; /* 当前点的行值,列值 */
  9.    int pre; /* 前一点在队列中的序号 */
  10. }QElemType,SElemType; /* 定义栈元素和队列元素 */
  11. #include"c3-1.h" /* 栈的存储结构 */
  12. #include"bo3-1.c" /* 栈的基本操作 */
  13. #include"c3-3.h" /* 队列的存储结构 */
  14. #include"bo3-4.c" /* 队列的基本操作 */

  15. struct /* 移动数组,移动方向由正东起顺时针转 */
  16. {
  17.    int x,y;
  18. #if D==8
  19. }move[D]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
  20. #endif
  21. #if D==4
  22. }move[D]={{0,1},{1,0},{0,-1},{-1,0}};
  23. #endif

  24. Status Path(int maze[M][N]) /* 广度搜索法求一条迷宫路径 */
  25. {
  26.    SqQueue q; /* 采用非循环顺序队列 */
  27.    QElemType qf,qt; /* 当前点和下一点 */
  28.    SqStack s; /* 采用顺序栈 */
  29.    int i,j,flag=1; /* 当找到出口,flag=0 */
  30.    int x1,y1; /* 终点的坐标 */
  31.    printf("请输入入口的行,列(左上角为1,1)\n");
  32.    scanf("%d,%d",&qf.x,&qf.y);
  33.    printf("请输入出口的行,列(右下角为%d,%d)\n",M-2,N-2);
  34.    scanf("%d,%d",&x1,&y1);
  35.    qf.pre=-1; /* 设入口(第一点)的上一点的序号=-1 */
  36.    maze[qf.x][qf.y]=-1; /* 初始点设为-1(已访问过) */
  37.    InitQueue(&q);
  38.    EnQueue(&q,qf); /* 起点入队 */
  39.    while(!QueueEmpty(q)&&flag)
  40.    { /* 队列中还有没被广度搜索过的点且还没找到出口 */
  41.      DeQueue(&q,&qf); /* 出队qf为当前点 */
  42.      for(i=0;i<D;i++) /* 向各个方向尝试 */
  43.      {
  44.        qt.x=qf.x+move[i].x; /* 下一点的坐标 */
  45.        qt.y=qf.y+move[i].y;
  46.        if(maze[qt.x][qt.y]==1)
  47.        { /* 此点是通道且不曾被访问过 */
  48.          maze[qt.x][qt.y]=-1; /* 已访问过 */
  49.          qt.pre=q.front-1; /* 上一点处于队列中现队头减一的位置(没删除) */
  50.          EnQueue(&q,qt); /* 入队 */
  51.          if(qt.x==x1&&qt.y==y1) /* 到达终点 */
  52.          {
  53.            flag=0;
  54.            break;
  55.          }
  56.        }
  57.      }
  58.    }
  59.    if(flag) /* 搜索完整个队列还没到达终点 */
  60.    {
  61.      printf("没有路径可到达终点!\n");
  62.      return ERROR;
  63.    }
  64.    else
  65.    {
  66.      InitStack(&s); /* 初始化s栈 */
  67.      i=q.rear-1; /* i为待入栈元素在队列中的位置 */
  68.      while(i>=0) /* 没到入口 */
  69.      {
  70.        Push(&s,*(q.base+i));
  71.        i=(*(q.base+i)).pre; /* i为前一元素在队列中的位置 */
  72.      }
  73.      i=0; /* i为走出迷宫的步骤 */
  74.      while(!StackEmpty(s))
  75.      {
  76.        Pop(&s,&qf);
  77.        i++;
  78.        maze[qf.x][qf.y]=i;
  79.      }
  80.      printf("走出迷宫的一个方案:\n");
  81.      for(i=1;i<M-1;i++) /* 输出maze[][],其值是走出迷宫的步骤 */
  82.      {
  83.        for(j=1;j<N-1;j++)
  84.          printf("%3d",maze[i][j]);
  85.        printf("\n");
  86.      }
  87.      return OK;
  88.    }
  89. }

  90. void main()
  91. {
  92.    int i,j;
  93.    int maze[M][N]; /* 迷宫数组 */
  94.    printf("%d行%d列迷宫(不包括外墙)\n",M-2,N-2);
  95.    for(i=0;i<N;i++)
  96.    { /* 0为墙,1为通道 */
  97.      maze[0][i]=0; /* 北墙 */
  98.      maze[M-1][i]=0; /* 南墙 */
  99.    }
  100.    for(i=1;i<M-1;i++)
  101.    {
  102.      maze[i][0]=0; /* 西墙 */
  103.      maze[i][N-1]=0; /* 东墙 */
  104.    }
  105.    printf("请按行输入迷宫结构(不包括周边,0为墙,1为通道),如1 0 0 1\n");
  106.    for(i=1;i<M-1;i++)
  107.      for(j=1;j<N-1;j++)
  108.        scanf("%d",&maze[i][j]);
  109.    printf("迷宫结构(包括外墙):\n");
  110.    for(i=0;i<M;i++)
  111.    {
  112.      for(j=0;j<N;j++)
  113.        printf("%3d",maze[i][j]);
  114.      printf("\n");
  115.    }
  116.    Path(maze);
  117. }
复制代码


回复

使用道具 举报

Archiver|手机版|小黑屋|三木电子社区 ( 辽ICP备11000133号-4 )

辽公网安备 21021702000620号

GMT+8, 2025-10-21 00:27 , Processed in 0.026048 second(s), 22 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表