zoukankan      html  css  js  c++  java
  • 迷宫求解

    迷宫求解描述:

    栈的方式——深度优先

    算法:

    1. 初始化栈,出发点先入栈
    2. 当栈不空时,出栈顶元素,当前位置不是墙壁并且没走过,标记已走
    3. 把相邻的四个位置压入栈,依次等待搜索
    4. 不断循环2-3,如果已经到达终点,退出循环
    #include "stdio.h"
    #define StackSize 100
    
    
    typedef struct{
      int i;
      int j;
    } ElemType;
    
    typedef struct {
      ElemType elem[StackSize];
      int top;
    }SqStack;
    
    InitStack(SqStack *pS)
    {
      pS->top=0; /* top指向栈顶的上一个元素 */
    }
    
    int Push(SqStack *pS,ElemType e)
    {
      if (pS->top==StackSize-1)   /* 栈满 */
        return 0;
    
      pS->elem[pS->top]=e;
      pS->top=pS->top+1;
      return 1;
    }
    
    int Pop(SqStack *pS,ElemType* pe)
    {
      if (pS->top==0)  /* 栈空 */
        return 0;
    
      pS->top = pS->top - 1;
      *pe = pS->elem[pS->top];
      return 1;
    }
    
    main()
    {
      SqStack S;
      ElemType e;
      int maze[10][10]={      /* 离散迷宫矩阵,0表示墙壁,1表示可以走的道路 */
        {0,0,0,0,0,0,0,0,0,0},
        {0,1,1,0,1,1,1,0,1,0},
        {0,1,1,0,1,1,1,0,1,0},
        {0,1,1,1,1,0,0,1,1,0},
        {0,1,0,0,0,1,1,1,1,0},
        {0,1,1,1,0,1,1,1,1,0},
        {0,1,0,1,1,1,0,1,1,0},
        {0,1,0,0,0,1,0,0,1,0},
        {0,0,1,1,1,1,1,1,1,0},
        {0,0,0,0,0,0,0,0,0,0}
      };
      int i,j,ti,tj;
    
      InitStack(&S); /* 初始化栈为空 */
    
      e.i=1;e.j=1;   /* 搜索的起点位置 */
      Push(&S,e);    /* 把起点位置入栈,准备搜索*/
    
      while(Pop(&S,&e)){          /* 当栈不空,则出栈并保存到e中 */
        if (maze[e.i][e.j]==1) {  /* 迷宫的当前位置不是墙壁并且没走过 */
          maze[e.i][e.j]=2;       /* 标记已走过 */
          if (e.i==8 && e.j==8)   /* 如果已经到达终点,退出循环 */
            break;
          else {
            /* 把相邻的四个位置压入栈,依次等待搜索,深度优先 */ 
            ti=e.i;  tj=e.j;
            e.i=ti-1; e.j=tj; Push(&S,e);  
            e.i=ti+1; e.j=tj; Push(&S,e);  
            e.i=ti; e.j=tj-1; Push(&S,e);
            e.i=ti; e.j=tj+1; Push(&S,e);  /* 最先搜索:右边位置 */ 
          }
        }
      }
    
    
      /* 打印出整个迷宫,2表示搜索过的位置。但是没有显示具体路径 */
      printf("
    
    ");
      for(i=0;i<10;i++) {
        for(j=0;j<10;j++)
          printf("%2d ",maze[i][j]);
        printf("
    ");
      }
    
      getch();
    }
    View Code

    另一种写法

    #include "stdio.h"
    #define StackSize 100
    
    typedef struct{
      int i,j;
    }PosType;
    
    typedef struct{
      PosType pos;
      int di;
    } ElemType;
    
    typedef struct {
      ElemType elem[StackSize];
      int top;
    }SqStack;
    
    InitStack(SqStack *pS)
    {
      pS->top=0; /* top指向栈顶的上一个元素 */
    }
    
    int Push(SqStack *pS,ElemType e)
    {
      if (pS->top==StackSize-1)   /* 栈满 */
        return 0;
    
      pS->elem[pS->top]=e;
      pS->top=pS->top+1;
      return 1;
    }
    
    int Pop(SqStack *pS,ElemType* pe)
    {
      if (pS->top==0)  /* 栈空 */
        return 0;
    
      pS->top = pS->top - 1;
      *pe = pS->elem[pS->top];
      return 1;
    }
    
    main()
    {
      SqStack S;
      ElemType e;
      PosType pos,pos_end;
      int maze[10][10]={      /* 离散迷宫矩阵,0表示墙壁 */
        {0,0,0,0,0,0,0,0,0,0},
        {0,1,1,0,1,1,1,0,1,0},
        {0,1,1,0,1,1,1,0,1,0},
        {0,1,1,1,1,0,0,1,1,0},
        {0,1,0,0,0,1,1,1,1,0},
        {0,1,1,1,0,1,1,1,1,0},
        {0,1,0,1,1,1,0,1,1,0},
        {0,1,0,0,0,1,0,0,1,0},
        {0,0,1,1,1,1,1,1,1,0},
        {0,0,0,0,0,0,0,0,0,0}
      };
      int i,j;
    
      InitStack(&S);
      pos_end.i=8;pos_end.j=8;
      pos.i=1;pos.j=1;
    
      do {
        if (maze[pos.i][pos.j]==1) {  /* 当前位置不是墙壁并且没走过 */
          maze[pos.i][pos.j]=2;   /* 标记已走过 */
          e.pos = pos;
          e.di = 1;
          Push(&S,e);           /* 加入路径 */
          if (pos.i==pos_end.i && pos.j==pos_end.j)     /* 如果已经到达终点,退出循环,求得的路径放在栈中 */
            break;
          else
            pos.j++;            /* 下一个位置是当前位置的右邻 */
        }
        else{  /* 当前位置不能通过 */
          if(S.top>0){
            Pop(&S,&e);
            while(e.di==4 && S.top>0){
              maze[e.pos.i][e.pos.j]=-1;  /* 留下不能通过的标记,并退回一步 */
              Pop(&S,&e);
            }
            if (e.di<4){
              e.di++; Push(&S,e);      /* 换下一个方向搜索 */
              pos.i=e.pos.i; pos.j=e.pos.j;
              if (e.di==2) pos.i++;    /* 设定当前位置是该方向上的相邻块“右下左上” */
              else if (e.di==3) pos.j--;
              else if (e.di==4) pos.i--;
            }
          }
        }
      }while(S.top>0);
    
    
      /* 求得的路径放在栈中 */
      printf("
    ");
      while(Pop(&S,&e))
        printf("
    (%d,%d)",e.pos.i,e.pos.j);
    
    
      /* 打印出整个迷宫,2的是所找到的路径,-1是走过的不通的路径 */
      printf("
    
    ");
      for(i=0;i<10;i++) {
        for(j=0;j<10;j++)
          printf("%2d ",maze[i][j]);
        printf("
    ");
      }
    
      getch();
    }
    View Code

    队列的方式——广度

    #include"stdio.h"
    #include"stdlib.h"
    
    #define Maxsize 100
    
    typedef struct{
        int i;
        int j;
        int pre;//记录前一个结点下标
    }DataType;//记录位置
    
    typedef struct {
        DataType data[Maxsize];
        int front,rear;
    }Queue;
    //初始化队列
    void InitQueue(Queue *Q)
    {
        Q->front=Q->rear=0;
    }
    //入队
    int InQueue(Queue *Q,DataType x)
    {
        if((Q->rear+1)%Maxsize==Q->front)
            return 0;
        Q->rear=(Q->rear+1)%Maxsize; //if (Q->rear+1)==Maxsize,Q->rear=0
        Q->data[Q->rear]=x;
        return 1;
    }
    //判断空队列
    int EmptyQueue(Queue *Q)
    {
        if(Q->rear==Q->front)
            return 1;
        else
            return 0;
    }
    //出队
    int OutQueue(Queue *Q,DataType *x)
    {
        if(EmptyQueue(Q))
            return 0;
        Q->front=(Q->front+1)%Maxsize;
        *x=Q->data[Q->front];
        return 1;
    }
    
    void main()
    {
        Queue Q;
        DataType x;
        int maze[10][10]={      /* 离散迷宫矩阵,0表示墙壁,1表示可以走的道路 */
            {0,0,0,0,0,0,0,0,0,0},
            {0,1,1,0,1,1,1,0,1,0},
            {0,1,1,0,1,1,1,0,1,0},
            {0,1,1,1,1,0,0,1,1,0},
            {0,1,0,0,0,1,1,1,1,0},
            {0,1,1,1,0,1,1,1,1,0},
            {0,1,0,1,1,1,0,1,1,0},
            {0,1,0,0,0,1,0,0,1,0},
            {0,0,1,1,1,1,1,1,1,0},
            {0,0,0,0,0,0,0,0,0,0}
        };
    
        InitQueue(&Q);
    
        int i,j,ti,tj;
        int di;
        x.i=1; x.j=1; //起始位置(1,1)
        x.pre=0;
        
        InQueue(&Q,x);
    
        while(OutQueue(&Q,&x))
        {
            if(x.i==8&&x.j==8)
                break;
            ti=x.i;  tj=x.j;
            for(di=0;di<4;di++)
            {
                switch(di)
                {
                case 0://
                    x.i=ti-1;
                    x.j=tj;
                    break;
                case 1://
                    x.i=ti+1;
                    x.j=tj;
                    break;
                case 2://
                    x.i=ti;
                    x.j=tj-1;
                    break;
                case 3://
                    x.i=ti;
                    x.j=tj+1;
                    break;
                }
                if(1==maze[x.i][x.j])//如果有路并且没有访问过
                {
                    x.pre=Q.front; 
                    x.i=x.i;x.j=x.j;
                    InQueue(&Q,x);
                    maze[x.i][x.j]=2; //表示已经访问过
                }
            }//for
        }
        
        
        printf("
    
    搜索过后的迷宫:
    ");
        for(i=0;i<10;i++) 
        {
            for(j=0;j<10;j++)
                printf("%2d ",maze[i][j]);
            printf("
    ");
        }
        printf("
    
    所走路线为(最短路线):
    ");
    
    //*
        do
        {
            printf("(%d,%d)	",Q.data[Q.front].i,Q.data[Q.front].j);
            Q.front=Q.data[Q.front].pre;
        }while(Q.front!=0);
        //*/
    }
    View Code

    递归的方式——深度优先

    #include "stdio.h"
    int SearchFun(int maze[][10],int i, int j)
    {
        if (maze[i][j]==1) {  /* 迷宫的当前位置不是墙壁并且没走过 */
          maze[i][j]=2;       /* 标记已走过 */
          if (i==8 && j==8)   /* 如果已经到达终点,返回 */
            return 1;
          else {
            /* 依次搜索相邻的四个位置,深度优先 */ 
            if (SearchFun(maze,i,j+1))   /* 最先搜索:右边位置 */
                return 1;
            if (SearchFun(maze,i,j-1))
                return 1;
            if (SearchFun(maze,i+1,j))
                return 1;
            if (SearchFun(maze,i-1,j))
                return 1;
          }
        }
        return 0;
    }
    
    main()
    {
      int maze[10][10]={      /* 离散迷宫矩阵,0表示墙壁,1表示可以走的道路 */
        {0,0,0,0,0,0,0,0,0,0},
        {0,1,1,0,1,1,1,0,1,0},
        {0,1,1,0,1,1,1,0,1,0},
        {0,1,1,1,1,0,0,1,1,0},
        {0,1,0,0,0,1,1,1,1,0},
        {0,1,1,1,0,1,1,1,1,0},
        {0,1,0,1,1,1,0,1,1,0},
        {0,1,0,0,0,1,0,0,1,0},
        {0,0,1,1,1,1,1,1,1,0},
        {0,0,0,0,0,0,0,0,0,0}
      };
      int i,j;
    
      SearchFun(maze,1,1);
    
    
      /* 打印出整个迷宫,2表示搜索过的位置。但是没有显示具体路径 */
      printf("
    
    ");
      for(i=0;i<10;i++) {
        for(j=0;j<10;j++)
          printf("%2d ",maze[i][j]);
        printf("
    ");
      }
    
      getch();
    }
    View Code
  • 相关阅读:
    HTML screenX 事件属性
    CSS Display(显示) 与 Visibility(可见性)
    JavaScript手册 | JS Array 对象中的sort() 方法
    IntelliJ IDEA收费版本Ultimate的安装和破解
    ASP.NET Style 控件
    HTML area hreflang 属性
    Shell test 命令
    ftplib (Internet) – Python 中文开发手册
    Java 之 Collection 接口
    java 之 集合概述
  • 原文地址:https://www.cnblogs.com/lisen10/p/10834917.html
Copyright © 2011-2022 走看看