|
|
Posted on 2006-04-09 23:26 laifangsong 阅读(2293) 评论(8) 编辑 收藏 网摘 所属分类: 算法
今天突然翻开了c语言数据结构,按照和课本上类似的思路,用c#重写了迷宫算法。
算法没有实现最短路径走法,如果你知道最短路径要怎么走,麻烦留言告诉我一下,谢谢!
1 using System; 2 using System.Collections; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Web; 7 using System.Web.SessionState; 8 using System.Web.UI; 9 using System.Web.UI.WebControls; 10 using System.Web.UI.HtmlControls; 11 12 namespace suanfa 13  { 14 /**//// <summary> 15 /// WebForm1 的摘要说明。 16 /// </summary> 17 public struct StackItem 18 { 19 public int order; 20 public int dir; 21 public Pos curPos; 22 } 23 public struct Pos 24 { 25 public int x; 26 public int y; 27 } 28 public class maze : System.Web.UI.Page 29 { 30 private void Page_Load(object sender, System.EventArgs e) 31 { 32 MazeStack(); 33 // 在此处放置用户代码以初始化页面 34 } 35 private void MazeStack() 36 { 37 //终点坐标 38 Pos dirPos = new Pos(); 39 dirPos.x = 8; 40 dirPos.y = 8; 41 //创建栈实例 42 Stack stack = new Stack(); 43 //结构体StackItem的实例为栈上的一项 44 StackItem stackItem = new StackItem(); 45 //初始化起点坐标 46 stackItem.curPos = new Pos(); 47 stackItem.curPos.x = 1; 48 stackItem.curPos.y = 1; 49 //序号 50 stackItem.order = 0; 51 //坐标下次移动朝向: 1.东 2.西 3.南 4.北 52 stackItem.dir = 0; 53 //初始化数组,0表示通路,1表示障碍 54 int [,] arrMaze = new int[10, 10] { 55 {1,1,1,1,1,1,1,1,1,1}, 56 {1,0,0,1,0,0,0,1,0,1}, 57 {1,0,0,1,0,0,0,1,0,1}, 58 {1,0,0,0,0,1,1,0,0,1}, 59 {1,0,1,1,1,0,0,0,0,1}, 60 {1,0,0,0,1,0,0,0,0,1}, 61 {1,0,1,0,0,0,1,0,0,1}, 62 {1,0,1,1,1,0,1,1,0,1}, 63 {1,1,0,0,0,0,0,0,0,1}, 64 {1,1,1,1,1,1,1,1,1,1} 65 }; 66 //输出用数组模拟的迷宫 67 for(int i=0; i<=arrMaze.GetUpperBound(0); i++) 68 { 69 for(int j=0; j<=arrMaze.GetUpperBound(1); j++) 70 { 71 Response.Write(arrMaze[i,j]); 72 } 73 Response.Write("<br>"); 74 } 75 Response.Write("<hr>"); 76 //主程序开始 77 do 78 { 79 switch(stackItem.dir) 80 { 81 case 1: 82 stackItem.curPos.y = stackItem.curPos.y + 1; 83 break; 84 case 2: 85 stackItem.curPos.x = stackItem.curPos.x + 1; 86 break; 87 case 3: 88 stackItem.curPos.y = stackItem.curPos.y - 1; 89 break; 90 case 4: 91 stackItem.curPos.x = stackItem.curPos.x - 1; 92 break; 93 default: 94 break; 95 } 96 if(stackItem.dir == 0) 97 { 98 stackItem.dir = 1; 99 } 100 if(arrMaze[stackItem.curPos.x,stackItem.curPos.y] == 0) 101 { 102 stackItem.order++; 103 stack.Push(stackItem); 104 //2表示已经走过 105 arrMaze[stackItem.curPos.x,stackItem.curPos.y] = 2; 106 if(stackItem.curPos.x == dirPos.x && stackItem.curPos.y == dirPos.y) 107 { 108 break; 109 } 110 stackItem.dir = 1; 111 } 112 else 113 { 114 if(stackItem.dir == 4) 115 { 116 if(stack.Count > 0) 117 { 118 stack.Pop(); 119 } 120 if(stack.Count > 0) 121 { 122 StackItem stackItemTemp = (StackItem)stack.Pop(); 123 stackItem.dir = stackItemTemp.dir; 124 stackItem.order = stackItemTemp.order; 125 stackItem.curPos.x = stackItemTemp.curPos.x; 126 stackItem.curPos.y = stackItemTemp.curPos.y; 127 if(stackItem.dir != 4) 128 { 129 stackItem.dir++; 130 } 131 stack.Push(stackItem); 132 } 133 } 134 else 135 { 136 if(arrMaze[stackItem.curPos.x,stackItem.curPos.y] != 0) 137 { 138 //退回前一个坐标 139 switch(stackItem.dir) 140 { 141 case 1: 142 stackItem.curPos.y = stackItem.curPos.y - 1; 143 break; 144 case 2: 145 stackItem.curPos.x = stackItem.curPos.x - 1; 146 break; 147 case 3: 148 stackItem.curPos.y = stackItem.curPos.y + 1; 149 break; 150 default: 151 break; 152 } 153 stackItem.dir++; 154 } 155 } 156 } 157 }while(stack.Count > 0); 158 //主程序结束 159 160 if(stack.Count > 0) 161 { 162 while(stack.Count > 0) 163 { 164 stackItem = (StackItem)stack.Pop(); 165 Response.Write(stackItem.order + "。" + "(" + stackItem.curPos.x + "," + stackItem.curPos.y + ")<br>"); 166 } 167 } 168 else 169 { 170 Response.Write("路径不通!"); 171 } 172 //清空栈 173 stack.Clear(); 174 } 175 Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码 176 override protected void OnInit(EventArgs e) 177 { 178 // 179 // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 180 // 181 InitializeComponent(); 182 base.OnInit(e); 183 } 184 185 /**//// <summary> 186 /// 设计器支持所需的方法 - 不要使用代码编辑器修改 187 /// 此方法的内容。 188 /// </summary> 189 private void InitializeComponent() 190 { 191 this.Load += new System.EventHandler(this.Page_Load); 192 193 } 194 #endregion 195 } 196 } 197
输出结果:
Feedback
要实现最短路径,只要稍稍做修改即可。
现在你用0表示通路,1表示障碍;
同时0表示未走,2表示走过——这样,你在“路过”这些0的时候,只是简单地把它们改为2,却并没有保存下你到达当前位置时走了多少步的信息。
所以,只要在“路过”的时候保存下“走到这里需要多少步”的信息,就可以找出最短路径了。
谢谢 smalldust 留言
你说的有点模糊,我不太懂,偶笨。。呵呵,我的疑问是:
比如我上面的程序,如果都没有障碍的话,立刻能得到一条到终点的可能不是最短的路径;程序从开始到执行完毕只走过了一条路。
在路上留下各步的 “走到这里需要多少步”,也只是针对这条路,好像没什么意义。
可能理解错了你的用意。。
@laifangsong
呵呵,不好意思,是我说的太笼统了。
的确如您所说,算法本身也需要修改。
如果没看错的话,您现在用的是一种“回溯”式的算法吧?
本质上和递归是一致的,使用了堆栈作为存储结构。
这道题如果要计算最短路径的话,我觉得使用队列作为存储结构比较方便。
先把起始点加入队列,然后再把队列里的每一个点的相邻点加入队列(加入的时候不要忘记更新到达它们的步数)……
这种“广度优先”的方法,就保证了先处理“距离近”的点,这样就能保证第一个找到的是最短路径了。
谢谢,有心了,还特意回复我。
我先去看看广度优先是怎么回事,呵呵。
|