苦思无果之余,某群友发了个帖子给我,我一看,同样是求2点间所有路径的算法,用的是C++和结点栈。
想法非常独特,引用了一个线的定义。完美解决了递归改为循环中的路径标记问题。
于是本人辛辛苦苦弄了半天终于把递归改为了while循环+结点栈。
测试后雷了……
花的时间竟然比原来的递归还多一点!我这是何苦来哉、、、
其实作者文章开头就已经声明了,效率不高。
但没想到比递归还要低,那还不如用递归呢?
该帖地址俺就不贴了。
下面是改过后的代码。估计是路径标记的判断和更新花费太多时间。看来需要从其他方面下手了。
private LinkedList<Point> paths;//当前键值集合
private LinkedList<Point>[] pathList;//所有路径列表
public int pathListIndex=-1;//路径列表index
public int totalPathNum = 0;//总路径数
public int maxFace = 0;//当前统计出的最大面数
public int maxFaceID = 0;//
Stopwatch timer;
public int[] times;
bool[,] pointIspath;
bool[,,,] lineIspath;
public void research ()
{
paths = new LinkedList<Point>();
paths.AddLast(startTile);
pathList = new LinkedList<Point>[5000];
pathListIndex = -1;
totalPathNum = 0;
maxFace = 0;
maxFaceID = 0;
pointIspath = new bool[20, 20];
lineIspath = new bool[20, 20, 20, 20];
times = new int[6];//计算时间
timer = new Stopwatch();
timer.Start();
times[0] = (int)timer.Elapsed.TotalMilliseconds;
//searchAll(startTile, paths);//递归
while (paths.Count>0)
{
//int[] tmpTimes = new int[5];
Point[] dir = new Point[4];//4个方向
int j = 0;
Point pointIn = paths.Last.Value;//当前循环入点
foreach (Point point in OpenMapTiles(pointIn))//遍历四周可走格子-pach和空位
{
dir[j] = point; j++;
}
//第一次循环,判断周围是否有终点,是否闭合
int i = 0;
int x=0;
for (x = 0; x < j; x++)//遍历四周可走格子-pach和空位
{
if (dir[x] == endTile)//只要有一格是终点
{
totalPathNum++;//总数+1
int temFaceNum = faceNumTest(paths);//计算面数
if (temFaceNum > maxFace)//如果大于当前最大面数,
{
maxFace = temFaceNum;
pathList = new LinkedList<Point>[5000];//重置list,并保存当前路径
pathList[0] = new LinkedList<Point>(paths);
pathListIndex = 1;
}
else if (temFaceNum == maxFace)//如果等于当前最大面数
{
pathList[pathListIndex] = new LinkedList<Point>(paths);//将路径付与路径列表
pathListIndex++;//数量+1
}
goto exitWhile;
}
else if (paths.Contains(dir[x]) && ++i > 1)//有2格是路径,说明闭合了。放弃
{
goto exitWhile;
}
}
//二次循环,遍历四周可走格子,只要右路就进,同时设置标识
for (x = 0; x < j; x++)//遍历四周可走格子-pach和空位
{
if (paths.Contains(dir[x])) continue;//路径坐标退出
if (!pointIspath[dir[x].X, dir[x].Y] && //如果2个标记都为空
!lineIspath[pointIn.X, pointIn.Y, dir[x].X, dir[x].Y])
{
pointIspath[dir[x].X, dir[x].Y] = true;//入栈标记
lineIspath[pointIn.X, pointIn.Y, dir[x].X, dir[x].Y] = true;//入栈标记
paths.AddLast(dir[x]);//入栈
break;
}
}
if (x < j) continue;//如有路径,直接循环
else
{
for (x = 0; x < j; x++)
{
lineIspath[pointIn.X, pointIn.Y, dir[x].X, dir[x].Y] = false;//清除入栈标记
}
}
exitWhile://找到路径 || 此路不通 || 循环无路
paths.RemoveLast();//出栈;
pointIspath[pointIn.X, pointIn.Y] = false;//取消标记
//更新line标记
}//while
times[0] = (int)timer.Elapsed.TotalMilliseconds - times[0];
Debug.WriteLine("-----------------------------");
Debug.WriteLine(times[0]);
//Debug.WriteLine(times[2]);
}