迷宫问题 POJ - 3984(dfs)

定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

根据给定数组建立二叉树
一次剪枝:剪掉到不了终点的
二次剪枝:剪掉不是最短的路线

#include <iostream>
#include <iomanip>

using std::cout;
using std::cin;
using std::endl;
using std::setw;
const int col = 5,row = 5;
typedef struct binTree* binTreep;
struct binTree
{
    int x;
    int y;
    binTreep left;
    binTreep right;
};

class AStack
{
    binTreep sta[100];
    int top;
public:
    AStack(){top = -1;}
    binTreep peek()const
    {
        return sta[top];
    }
    binTreep pop()
    {
        if(top != -1)
            return sta[top--];
        return NULL;
    }
    void push(binTreep x)
    {
        sta[++top] = x;
    }
    int isEmpty()const
    {
        return top == -1;
    }
};
binTreep CBTbyTDA(int row_,int col_,int (*map)[col]);
void NIO(binTreep root);
void DST(binTreep root);
int isCut(binTreep root);
void cut_first(binTreep root);
void cut_second(binTreep root);
int height_min(binTreep root);
int main()
{

    int map[row][col] ;//= {{0,1,0,0,0},{0,1,0,1,0},{0,0,0,0,0},{0,1,1,1,0},{0,0,0,1,0}};

    for(int i = 0; i < row; i++)
        for(int j = 0; j < col; j++)
            cin >> map[i][j];

    int (*p)[col] = map;
    binTreep root = CBTbyTDA(0,0,p);
    cut_first(root);
    cut_second(root);

    NIO(root);
    return 0;
}
void cut_second(binTreep root)
{
    if(root == NULL)
        return;
    if(root->left && root->right)
    {
        int leftHeight = height_min(root->left),rightHeight = height_min(root->right);
        if(leftHeight > rightHeight)
        {
            DST(root->left);
            root->left = NULL;
        }
        else
        {
            DST(root->right);
            root->right = NULL;
        }
    }
    else if(root->left)
        cut_second(root->left);
    else if(root->right)
        cut_second(root->right);
}
void cut_first(binTreep root)
{
    if(root == NULL)
        return;
    if(isCut(root->left))
    {
        DST(root->left);
        root->left = NULL;
    }
    else
    {
        if(root->left)
            cut_first(root->left);
    }
    if(isCut(root->right))
    {
        DST(root->right);
        root->right = NULL;
    }
    else
    {
        if(root->right)
            cut_first(root->right);
    }
}
int isCut(binTreep root)
{
    if(root == NULL)
        return 1;
    int li = 1,ri = 1;
    if(root->left)
        li = isCut(root->left);
    if(root->right)
        ri = isCut(root->right);
    if(root->x == row - 1 && root->y == col - 1)
        return 0;
    return li && ri;
}
binTreep CBTbyTDA(int row_,int col_,int (*map)[col])
{
    binTreep nodep = new binTree;
    nodep->x = row_;
    nodep->y = col_;
    if(row_ + 1 >= row || map[row_ + 1][col_] == 1)
        nodep->left = NULL;
    else
        nodep->left = CBTbyTDA(row_ + 1,col_,map);
    if(col_ + 1 >= col || map[row_][col_ + 1] == 1)
        nodep->right = NULL;
    else
        nodep->right = CBTbyTDA(row_,col_ + 1,map);
    return nodep;
}

void NIO(binTreep root)
{
    AStack S;
    binTreep p = root;
    while(p || !S.isEmpty())
    {
        while(p)
        {
            cout << '('  << p->x << ',' << ' ' << p->y << ')' << endl;
            S.push(p);
            p = p->left;
        }
        p = S.pop();
        p = p->right;
    }
}

int height_min(binTreep root)
{
    if(root == NULL)
        return 0;
    if(root->x == row - 1 && root->y == col - 1)
        return 1;
    int leftLen = 0,rightLen = 0;
    leftLen = height_min(root->left);
    rightLen = height_min(root->right);
    if(leftLen && rightLen)
        return 1 + leftLen > rightLen ? leftLen : rightLen;
    if(leftLen)
        return 1 + leftLen;
    if(rightLen)
        return 1 + rightLen;
}
void DST(binTreep root)
{
    if(root == NULL)
        return;
    if(root->left)
        DST(root->left);
    if(root->right)
        DST(root->right);
    delete root;
}
发布了39 篇原创文章 · 获赞 4 · 访问量 5746

猜你喜欢

转载自blog.csdn.net/weixin_45725137/article/details/105613643