非递归算法尝试1!
苦思无果之余,某群友发了个帖子给我,我一看,同样是求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]); }