c语言数据结构之迷宫问题

c语言数据结构之迷宫问题

代码100%可以远行!!

迷宫问题求解
(一)思路:
首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d 表示走到下一坐标的方向。

typedef struct Data
{
int abscissa; // x
int ordinate; // y
int direction;
} Data;

计算机解迷宫通常用的是“穷举求解”方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。可以二维数组存储迷宫数据,通常设定入口的下标为(1,1),出口点的下标为(n,n)。为处理方便起见,可在迷宫的四周加一圈障碍。对于迷宫中任一位置,均可约定有东、南、西、北四个方向可通。

(二)步骤分析
1、用二维数组存放0,1来分别表示迷宫中可走方块以及不可走方块。
2、从入口处开始,顺时针方向去试探当前方块的四个方位(上,左,下,右)。
3、在当前位置寻找四个方位中的可走方块。若当前试探方位可走。则将该试探方位的方块入栈, 并将此时走过的方块置为不可走(这里将值置为-1),以防止两个方块来回进入死循环,此时试 探方位的方块在栈的顶部,再用栈顶方块继续对四个方位进行试探。若当前方块的四个试探方 位都无法前进。则将当前方块退栈,并将退栈方块的值恢复为0,然后找此时栈顶方块的其他 可能的相邻方块。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define Row 8
#define Col 9
// typedef int ElemenType;

typedef struct Data
{
    int abscissa; // x
    int ordinate; // y
    int direction;
} Data;

typedef struct StackNode
{
    Data data;
    struct StackNode *next;
} StackNode;

int directions[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

int maze[Col + 2][Row + 2] = {
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
    {1, 0, 0, 1, 0, 0, 0, 1, 0, 1},
    {1, 0, 0, 1, 0, 0, 0, 1, 0, 1},
    {1, 0, 0, 0, 0, 1, 1, 0, 1, 1},
    {1, 0, 1, 1, 1, 0, 0, 1, 0, 1},
    {1, 0, 0, 0, 1, 0, 0, 0, 0, 1},
    {1, 0, 1, 0, 0, 0, 1, 0, 1, 1},
    {1, 0, 1, 1, 1, 1, 0, 0, 1, 1},
    {1, 1, 1, 0, 0, 0, 1, 0, 1, 1},
    {1, 1, 1, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};

//初始化
StackNode *Init(void)
{
    StackNode *top;
    top = (StackNode *)malloc(sizeof(StackNode));
    top->next = NULL;

    return top;
}

//进栈
void Push(StackNode *top, Data data)
{
    StackNode *p;
    p = (StackNode *)malloc(sizeof(StackNode));
    if (!p)
    {
        printf("申请新结点失败!!\n");
    }
    else
    {
        //前插入法
        p->data = data;
        p->next = top->next;
        top->next = p;
    }
    printf("%d,%d 进栈\n", data.ordinate, data.abscissa);
}

//出栈
void Pop(StackNode *top)
{
    StackNode *p;
    Data data;
    if (p->next == NULL)
    {
        printf("栈空!!\n");
    }
    else
    {
        p = top->next;
        data = p->data;      /* 取栈顶元素 */
        top->next = p->next; /*修改栈顶指针*/
        free(p);
        printf("%d,%d出栈!!\n", data.ordinate, data.abscissa);
    }
}

void Run()
{
    StackNode *top = Init();
    Data data;
    int x1, y1, d1, find;

    data.abscissa = 1;
    data.ordinate = 1;
    data.direction = -1;
    Push(top, data);

    while (top->next != NULL)
    {
        x1 = top->next->data.abscissa;
        y1 = top->next->data.ordinate;
        d1 = top->next->data.direction;

        //输出路径逻辑
        if (x1 == Col && y1 == Row)
        {
            printf("找到路径:");
            StackNode *p;
            p = top->next;
            while (p != NULL)
            {
                printf("(%d,%d)", p->data.ordinate, p->data.abscissa);
                p = p->next;
            }
            printf("\n");
            break;
        }

        //查找下一个节点
        find = 0;
        while (find == 0 && d1 < 4)
        {
            d1++;
            switch (d1)
            {
            //向上
            case 0:
                x1 = top->next->data.abscissa;
                y1 = top->next->data.ordinate - 1;
                break;

            //右
            case 1:
                x1 = top->next->data.abscissa + 1;
                y1 = top->next->data.ordinate;
                break;

            //向下
            case 2:
                x1 = top->next->data.abscissa;
                y1 = top->next->data.ordinate + 1;
                break;

            //向左
            case 3:
                x1 = top->next->data.abscissa - 1;
                y1 = top->next->data.ordinate;
                break;
            default:
                break;
            }

            if (maze[x1][y1] == 0)
            {
                find = 1;
            }
        }

        //找到下一个节点
        if (find == 1)
        {
            top->next->data.direction = d1;
            data.abscissa = x1;
            data.ordinate = y1;
            data.direction = -1;

            //走过的节点置1不可通行
            Push(top, data);
            maze[x1][y1] = 1;
        }
        else
        {
            //该节点可通行
            maze[top->next->data.abscissa][top->next->data.ordinate] = 0;
            Pop(top);
        }
    }
}

int main()
{
    clock_t start, finish;
    start = clock();
    Run();
    finish = clock();
    printf("运行用时:%f 秒!\n", (double)(finish - start) / CLOCKS_PER_SEC);
}
  • 6
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: OK,我理解了,您的问题是关于C语言数据结构迷宫问题C语言中,实现迷宫问题主要涉及到两个方面:一是地图的表示方式;二是搜索算法的实现。 对于地图的表示方式,可以使用二维数组来表示。假设地图的大小为m*n,那么我们可以定义一个m行n列的二维数组,每个元素表示一个地图上的位置。如果该位置可以通行,则标识为1,否则为0。 对于搜索算法的实现,可以使用广度优先搜索(BFS)或深度优先搜索(DFS)等算法。以BFS为例,其基本思路是从起点开始搜索,将其周围的位置加入队列中,然后从队列中取出一个位置进行搜索,直到找到终点或者队列为空为止。 在实现过程中,还需要考虑如何表示队列等数据结构,如何标识已经访问过的位置等问题。 希望以上内容能够对您有所帮助。如果您有任何问题或需要进一步的帮助,请随时向我提问。 ### 回答2: 迷宫问题是指在一个二维矩阵中,通过移动来找到从起点到终点的路径。C语言是一种用于程序设计的高级编程语言,可以处理各种数据结构。在利用C语言解决迷宫问题时,我们可以使用数据结构来表示迷宫并实现路径的查找。 在C语言中,我们可以使用二维数组来表示迷宫,其中不同的值代表不同的状态,比如起点、终点、墙壁和通道等。可以使用一个结构体来表示迷宫的坐标位置。 要解决迷宫问题,可以使用递归或者回溯算法。递归算法通过不断地探索下一个可行的位置,直到找到终点或者无法继续前进时回溯到上一个位置。回溯算法则是通过记录已经尝试过的路径,在无法继续前进时回到上一个节点再进行其他尝试。 在C语言中,我们可以使用递归函数来实现迷宫问题的解决。通过将当前位置标记为已访问,在每个可行的方向上递归调用自身,直到找到终点或者无法继续前进。如果找到了终点,则递归函数返回真,并将路径输出。否则,递归函数返回假,表示无法找到合适的路径。 总结来说,C语言可以通过二维数组和结构体来表示迷宫问题。使用递归函数和回溯算法可以在迷宫中找到从起点到终点的路径。通过灵活运用C语言数据结构,我们可以解决各种迷宫问题。 ### 回答3: 在C语言中实现迷宫问题涉及到使用数据结构来解决迷宫中的路径搜索问题。可以使用二维数组表示迷宫地图,其中0表示空地,1表示墙壁。通过使用二维数组来表示迷宫,可以方便地在程序中操作迷宫地图。 解决迷宫问题的一个常见的方法是使用深度优先搜索算法。通过递归调用函数,在每个可能的路径上继续向前探索,直到找到一条通向终点的路径或者无路可走。在搜索过程中,需要使用访问标记数组来记录已经访问过的位置,避免陷入死循环。 具体实现时,可以定义一个递归函数,该函数可以接受迷宫地图、起始位置、目标位置等参数。在函数内部,首先判断当前位置是否为终点,如果是则返回true,表示找到了一条路径。然后根据当前位置进行上、下、左、右的四个方向探索,如果该方向可以走,并且没有访问过,则递归调用函数,继续向前探索。如果四个方向都无路可走,则返回false。 在每个递归调用中,需要更新访问标记数组,并将当前位置加入到路径中。如果找到了一条通向终点的路径,则可以将路径输出或者保存下来。 总之,使用C语言数据结构解决迷宫问题,可以通过二维数组表示迷宫地图,使用深度优先搜索算法进行路径搜索,同时使用访问标记数组避免陷入死循环。这样可以找到迷宫中从起点到终点的一条路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值