用WPF做演示

1.用Stack记录和回溯

在现实生活中,在你迷路的时候,总是记录一些可记忆的建筑物作为返回的标志(比如你出去玩,总得回家的吧,那么就得记得回家的路)

(1)画迷宫

public class MazeElement : FrameworkElement
{
public MazeElement(int[,] mg)
{
this.mg = mg;
}

int[,] mg=null;

protected override void OnRender(DrawingContext dc)
{
var width = 40;
dc.DrawRectangle(Brushes.Black, null, new Rect(0, 0, 10 * width, 10 * width));
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (mg[i, j] == 1)
{
dc.DrawRectangle(Brushes.Gray, null, new Rect(j * (width), i * (width), width - 1, width - 1));
}
else
{
dc.DrawRectangle(Brushes.White, null, new Rect(j * (width), i * (width), width - 1, width - 1));
}
}
}
}
}


栈和队列 迷宫求解_数据结构

(2)白色表示可以通过的坐标,从坐标1,1寻找坐标(8,8)点

一个块的的数据结构如下,即坐标点加下个可寻找点的方向

public class Block
{
public Point Point { get; set; }

public int Direction { get; set; }
}


(3)若找到的下个是白点且没有重复的话,则继续寻找,否则就回溯,找另外的出口,其实就是穷举法了…

算法如下

public void MgPath(Point start, Point end)
{

Block temp = null;
bool find = false;
while (st.Count > 0)
{
temp = st.Peek();
_point = temp.Point;

Console.WriteLine(temp.Point.ToString());
var point = temp.Point;
var di = temp.Direction;

//UI Refresh don't care
System.Threading.Thread.Sleep(100);
Dispatcher.BeginInvoke(new Action(() =>
{
this.InvalidateVisual();
}), DispatcherPriority.Render);

if (point.Equals(end))
{
finished = true;
break;
}

//not find
find = false;
//find next block
while (di < 4 && !find)
{
di++;
switch (di)
{
case 0://top
point.Y = temp.Point.Y - 1;
point.X = temp.Point.X;
break;
case 1://right
point.X = temp.Point.X + 1;
point.Y = temp.Point.Y;
break;
case 2://bottom
point.Y = temp.Point.Y + 1;
point.X = temp.Point.X;
break;
case 3://left
point.X = temp.Point.X - 1;
point.Y = temp.Point.Y;
break;
}
if (mg[(int)point.X, (int)point.Y] == 0) find = true;
}
//if find
if (find)
{
temp.Direction = di;
st.Push(new Block() { Point = point, Direction = -1 });
//mark already visit
mg[(int)point.X, (int)point.Y] = -1;
}
else
{
//not find
mg[(int)temp.Point.X, (int)temp.Point.Y] = 0;
st.Pop();
}
break;
}
}