数据结构_利用栈和队列实现走迷宫_BFS_DFS

数据结构_利用栈和队列实现走迷宫_BFS_DFS

预定义.h

#ifndef PROGRAM1_预定义_H
#define PROGRAM1_预定义_H

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
// Status 是函数的类型, 其值是函数结果状态代码
typedef int Status;

#endif //PROGRAM1_预定义_H

Stack.h

#pragma once

#include "预定义.h"
#include <stdio.h>
#include <stdlib.h>

typedef int Status;


#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef struct
{
    int x, y;  //行列坐标
    int d;  //上一点来此的方向
} datatype;
typedef datatype SElemType;

typedef struct
{
    datatype* base, * top;
    int stacksize;
} SqStack;
SqStack S;


Status InitStack(SqStack &S);

Status DestroyStack(SqStack &S);

Status ClearStack(SqStack &S);

Status StackEmpty(SqStack S);

//int StackLength(SqStack S);

Status GetTop(SqStack S, SElemType &e);

Status Push(SqStack &S, SElemType e);

Status Pop(SqStack &S, SElemType &e);

void PrintStack(SqStack S);

Status InitStack(SqStack &S)
{
    S.base = (datatype*) malloc(STACK_INIT_SIZE * sizeof(datatype));
    if (!S.base)
        exit(OVERFLOW);
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}

Status GetTop(SqStack S, SElemType &e)
{
    if (S.top == S.base) return ERROR;
    e = *(S.top - 1);
    return OK;
}

Status Push(SqStack &S, SElemType e)
{
    if (S.top - S.base >= S.stacksize)
    {
        //栈满, 追加存储空间
        S.base = (SElemType*) realloc(S.base,
                                      (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
        if (!S.base)
            exit(OVERFLOW);
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    *S.top++ = e;  //记住此处是先取值后自加.
    return OK;
}

Status Pop(SqStack &S, SElemType &e)
{
    if (S.top == S.base)
        return ERROR;
    e = *--S.top;
    return OK;
}

Status StackEmpty(SqStack S)
{
    if (S.top == S.base)
        return TRUE;
    return FALSE;
}

Status DestroyStack(SqStack &S)
{
    if (!S.base)
        return ERROR;
    free(S.base);
    S.base = S.top = NULL;
    S.stacksize = 0;
    return OK;
}

Status ClearStack(SqStack &S)
{
    if (!S.base)
        return ERROR;
    SElemType e;
    while (!StackEmpty(S))
    {
        GetTop(S, e);
        printf_s("%d", e);
    }
    //  S.top = S.base;
    return OK;
}

void PrintStack(SqStack S)
{
    printf_s("迷宫走法之一:\n");
    SElemType* p = S.base, * q = S.top;
    while (p != q)
    {
        printf_s("<%d %d>\n", p->x, p->y);
        p++;
    }
}

Queue.h

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include "预定义.h"

#define MAXQSIZE 100
typedef struct
{
    int x, y;//  所到达点的坐标
    int pre;  // 是从哪个坐标到达本节点坐标的, 即队列中前驱节点的数组下标
} QElemType;

typedef struct
{
    QElemType base[MAXQSIZE];
    // QElemType* base;
    int front;  //头指针, 若队列不为空, 指向队列头元素
    int rear;  //尾指针, 若队列不空, 指向队列尾元素的下一个位置
} SqQueue;

/* ---- 基本函数列表及其实现 ---- */

int InitQueue(SqQueue &Q)
{
    Q.front = Q.rear = 0;
    return OK;
}

int QueueLength(SqQueue Q)
{
    return Q.rear - Q.front;
}

int EnQueue(SqQueue &Q, QElemType e)
{
    if (QueueLength(Q) > MAXQSIZE)
        return ERROR;
    Q.base[Q.rear] = e;
    Q.rear++;
    return OK;
}

int DeQueue(SqQueue &Q, QElemType &e)
{
    if (Q.front == Q.rear)
        return ERROR;
    e = Q.base[Q.front];
    Q.front++;
    return OK;
}

int EmptyQueue(SqQueue Q)
{
    if (Q.front == Q.rear)
        return 1;
    return 0;
}

void PrintQueue(SqQueue Q)
{
    printf_s("迷宫走法之一:\n");
    int j = Q.rear;
    j--;  //如果是要找到全部路线, 要在此处自减, 而不是在上一条语句自减
    while (j != -1)
    {
        printf_s("<%d %d> pre:%d\n", Q.base[j].x, Q.base[j].y, Q.base[j].pre);
        j = Q.base[j].pre;
    }

}

main.cpp

//学习使用DFS与BFS
#include <stdio.h>
#include "Stack.h"
#include "Queue.h"

/* ---- 一些重要的全局变量 ---- */
const int m = 9, n = 9;
int maze[m + 2][n + 2];  //迷宫
int moveX[] = {0, 1, 0, -1};  //X方向的移动, 从前到后依次是 东 南 西 北
int moveY[] = {1, 0, -1, 0};  //Y方向上的移动, 从前到后依次是 东 南 西 北
//X0 用于标记那些是为零的点
int X0[] = {1, 4, 5, 6, 8, 9, -1,
            1, 2, 3, 5, 7, 8, -1,
            1, 5, 8, 9, -1,
            1, 2, 3, 4, 5, 6, 7, 9, -1,
            3, 5, 7, 8, 9, -1,
            1, 2, 3, 5, 7, 9, -1,
            2, 6, 7, 8, 9, -1,
            1, 2, 3, 4, 5, 6, 9, -1,
            2, 5, 7, 8, 9, -1
};

void PrintTheMaze();

int DFS();

void BFS();

int main()
{
    //初始化迷宫.
    int i, j;
    for (i = 0; i < m + 2; i++)
        for (j = 0; j < n + 2; j++)
            maze[i][j] = 1;

    //规范化迷宫
    for (j = 1, i = 0; j < n + 2 - 1; i++)
    {
        if (X0[i] == -1)
        {
            j++;
            continue;
        }
        maze[j][X0[i]] = 0;  //此处 j 与 X0[i] 之间的前后关系不要搞错
        //printf("<%d %d>\n",X0[i],j);
    }
    PrintTheMaze();
    BFS();
    //DFS();
}

void BFS()
{
    int startX = 1, startY = 1;
    int endX = 7, endY = 7;
    int d = -1;
    int X = startX, Y = startY, Pre;

    SqQueue Q;
    InitQueue(Q);
    QElemType temp;

    temp.x = X, temp.y = Y, temp.pre = -1;
    EnQueue(Q, temp);
    maze[X][Y] = -1;

    while (!EmptyQueue(Q))
    {
        DeQueue(Q, temp);
        X = temp.x, Y = temp.y;
        if (temp.pre == -1)
            Pre = 0;
        else
            Pre = Q.front - 1;

        d = 0;
        while (d < 4)
        {
            if (maze[X + moveX[d]][Y + moveY[d]] != 1 && maze[X + moveX[d]][Y + moveY[d]] != -1)
            {
                temp.x = X + moveX[d], temp.y = Y + moveY[d];
                temp.pre = Pre;
                EnQueue(Q, temp);

                maze[X + moveX[d]][Y + moveY[d]] = -1;

                if (X + moveX[d] == endX && Y + moveY[d] == endY)
                {
                    maze[endX][endY] = 0;  //终点可重复到达.
                    printf_s("Success!\n");
                    PrintQueue(Q);
                    //  DestroyQueue(Q);
                    return; /* 如果要找到全部路线, 将此处的 return; 去掉即可 */
                }
            }
            d++;
        }
    }
}

int DFS()
{

    int startX = 1, startY = 1;
    int endX = 7, endY = 7;
    int d = -1;
    int X = startX, Y = startY;


    SqStack S;
    InitStack(S);
    SElemType temp;

    temp.x = startX, temp.y = startY;
    temp.d = -1;
    Push(S, temp);
    maze[X][Y] = -1;


    while (!StackEmpty(S))
    {
        Pop(S, temp);
        X = temp.x, Y = temp.y;
        d = temp.d;
        d++;
        while (d < 4)
        {
            if (maze[X + moveX[d]][Y + moveY[d]] != 1 && maze[X + moveX[d]][Y + moveY[d]] != -1)
            {
                temp.x = X, temp.y = Y, temp.d = d;
                Push(S, temp);
                X = X + moveX[d], Y = Y + moveY[d];
                printf_s("<%d %d>\n", X, Y);  //将到达点的坐标打印出来

                maze[X][Y] = -1;
                if (X == endX && Y == endY)
                {
                    temp.x = X, temp.y = Y, temp.d = d;
                    Push(S, temp);
                    printf_s("Success!\n");
                    PrintStack(S);
                    DestroyStack(S);
                    return 1;
                }
                else
                    d = 0;  //表示从此节点开始再次从正东尝试
            }
            else
                d++;  //换一个方向
        }
    }
}

void PrintTheMaze()
{
    int i, j;
    //打印迷宫
    for (i = 0; i < m + 2; i++)
    {
        for (j = 0; j < m + 2; j++)
            printf("%d ", maze[i][j]);
        printf_s("\n");
    }
}

迷宫图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值