非递归算法尝试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]);

        }

  

posted @ 2012-03-18 21:15  妖気  阅读(518)  评论(0编辑  收藏  举报