数据结构复习 队列(迷宫)

using System;
using System.Collections.Generic;
using System.Text;

namespace 队列应用迷宫
{
    class Program
    {
        static void Main(string[] args)
        {
            new mg(20, 20);
        }
    }

    class node
    {
        public int x;//第一维坐标
        public int y;//第二维坐标
        public int pre;//到达该结点的前导结点在队列的序号,可依靠它得到路径

        public node(int vx, int vy, int vpre)
        {
            x = vx;
            y = vy;
            pre = vpre;
        }
    }

    class mg
    {
        node[] query;// 走迷宫时回溯队列
        int[,] mgjm;// 迷宫界面二维数组

        // 结点周围8个方向
        int[] zx ={ -1, -1, 0, 1, 1, 1, 0, -1 };
        int[] zy ={ 0, 1, 1, 1, 0, -1, -1, -1 };

        public mg(int width, int height)
        {      
            // 队列初始化
            query = new node[(height-2)*(width-2)];
            int front, rear;
            front = rear = -1;

            // 迷宫界面初始化
            mgjm = new int[height, width];
            Random rand = new Random();
            for (int k = 0; k < height; k++)
            {
                for (int l = 0; l < width; l++)
                {
                    if (k == 0 || k == height - 1 || l == 0 || l == width - 1)
                    {// 周围的墙壁
                        mgjm[k, l] = 1;
                    }
                    else
                    {// 随即生成空挡或墙壁
                        mgjm[k, l] = rand.Next(100) % 2;
                    }
                }
            }

            // 保证开始点、结束点为空挡
            mgjm[1, 1] = 0;
            mgjm[height - 2, width - 2] = 0;

            // 开始点入队列
            query[++rear] = new node(1, 1, -1);
           
            mgjm[1, 1] = 2;// 进入队列的点就已经来过了,变成2

            int i;

            while (front < rear)
            {// 队列非空时循环

                node nodeTmp = query[++front];// 出队列
                for (i = 0; i < 8; i++)
                {// 8个方向循环

                    int tmpx = nodeTmp.x + zx[i];
                    int tmpy = nodeTmp.y + zy[i];

                    if (mgjm[tmpx, tmpy] == 0)
                    {// 如果是空挡

                        query[++rear] = new node(tmpx, tmpy, front);// 入队列
                        mgjm[tmpx, tmpy] = 2;// 置为已来过

                        if (tmpx == height - 2 && tmpy == width - 2)
                        {// 已到达结束点
                            break;
                        }
                    }
                }
                if (i < 8)
                {// 已到达结束点
                    break;
                }
            }

            StringBuilder strB = new StringBuilder();

            if (mgjm[height - 2, width - 2] == 2)
            {// 到达过结束点
                Console.WriteLine("yes");

                // 拼接路径
                strB.Append("(" + query[rear].x.ToString() + "," + query[rear].y.ToString() + ")");
                int preNode = query[rear].pre;
                while(preNode>=0)
                {
                    strB.Append("|(" + query[preNode].x.ToString() + "," + query[preNode].y.ToString() + ")");
                    preNode = query[preNode].pre;
                }
            }
            else
            {// 无法到达结束点
                Console.WriteLine("no");
            }

            // 打印迷宫
            for (int m = 0; m < height; m++)
            {
                for (int n = 0; n < width; n++)
                {
                    if (strB.ToString().IndexOf("(" + m.ToString() + "," + n.ToString() + ")") != -1)
                    {// 路径
                        Console.Write("* ");
                    }
                    else
                    {
                        Console.Write(mgjm[m, n].ToString() + " ");
                    }
                }
                Console.Write("/r/n");
            }

            // 打印路径坐标
            string[] arrTmp = strB.ToString().Split('|');
            for (int k = arrTmp.Length - 1; k >= 0; k--)
            {
                Console.Write(arrTmp[k] + "->");
            }
            Console.Write("/b/b ");
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值