迷宫问题讨论--(堆栈)
一:迷宫问题用堆栈的方法:
求迷宫中一条从入口到出口的路径的算法可简单描述如下:
设定当前位置的初值为入口位置:
do{
若当前位置可通,
则{ 将当前位置插入堆栈顶;
若该位置是出口位置,则结束;
否则切换当前位置的东邻块为新的当前位置;
}
否则,
若堆栈不空且栈顶位置尚有其他方向未经探索;
则设定新的当前位置为沿顺时针方向转到的栈顶位置的下一相邻块;
若栈不空但栈顶位置的四周均不可通,
则{删去栈顶位置;
若栈不空,则重新测试新的栈顶位置,
直至找到一个可通的相邻或出栈至栈空;
}
}(栈不空)
typedef struct{
int ord; //通道块在路径上的"序号"
PosType seat; //通道块在迷宫中的"坐标位置"
int di; //从此通道块走向下一通道块的"方向"
}SElemType; //堆栈的元素类型
Status MazePath(MazeType maze,PosType start,PosType end)
{
//若迷宫maze中存在从入口start到出口end的通道,则求得一条存放在栈中(从栈底到栈顶),并返回TRUE;否则返回FALSE
InitStack(S);
curpos=start; //设定"当前位置"为"入口位置"
curstep=1; //探索第一步
do{
if(Pass(curpos)){ //当前位置可以通过,即是未曾到过的通道.
FootPrint(curpos);//留下足迹
e=(curstep,curpos,1);
Push(S,e); //加入路径
if(curpos==end) return(TRUE);//到达终点(出口)
curpos=NextPos(curpos,1);//下一步是当前位置的东邻
curstep++; //探索下一步
}
else{ //当前位置不能通过
if (!StackEmpty(S)){
Pop(S,e);
while(e.di==4&&!StackEmpty(S)) {
MarkPrint(e.seat;Pop(S,e));//留下不能通过的标志,并退回一步
}
if(e.di<4){
e.di++;Push(S,e); //换下一个方向探索
curpos=NextPos(e.seat, e.di); //设定当前位置是该新方向上的相邻块
}
}
}
}while(!StackEmpty(S));
return(FALSE);
}
posted on 2004年06月26日 2:13 AM
反馈
我试了一下,并看了msdn的解释,好像stack类不支持一次将多个值压入或弹出,这是可以理解的,但如何将struct结构元素压入或弹出呢?谁知道这是什么原因呢?
代码如下:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace stkmaze
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
public int i,j,dir;
public const int maxsize = 100;
static public int[] movei=new int []{-1,-1,0,1,1,1,0,-1};
static public int[] movej=new int []{0,1,1,1,0,-1,-1,-1};
static int rows=5;
static int columns=9;
public bool stopmaze=false;
public int [,] maze=new int[5,9]{ {1,1,1,1,1,1,1,1,1},
{1,0,1,0,0,0,1,0,1},
{1,1,0,0,0,1,0,0,1},
{1,0,1,1,0,0,1,0,1},
{1,1,1,1,1,1,1,1,1}};
public int curi=1,curj=1,d=2,nexti,nextj;
public int[] nextd=new int [2];
Stack stki = new Stack();
Stack stkj = new Stack();
Stack stkdir = new Stack();
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label2;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
int i,j;
string a;
for (i=0;i<5;i++)
{
textBox1.AppendText("/n");
for(j=0;j<9;j++)
{
a = Convert.ToString(maze[i,j]);
textBox1.AppendText(a);
textBox1.AppendText(" ");
}
}
}
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(134)));
this.textBox1.Location = new System.Drawing.Point(16, 24);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(256, 240);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "";
this.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// label1
//
this.label1.Location = new System.Drawing.Point(280, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(80, 200);
this.label1.TabIndex = 1;
this.label1.Text = "该M×N(本例取5×9)迷宫(矩阵)最外面一圈为1,其中1表示不可通过,0表示可通过。代码里已输入迷宫(矩阵)后再按“走迷宫”按钮。";
//
// button1
//
this.button1.Location = new System.Drawing.Point(280, 240);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(80, 24);
this.button1.TabIndex = 2;
this.button1.Text = "走迷宫";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label2
//
this.label2.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(134)));
this.label2.Location = new System.Drawing.Point(80, 8);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(136, 16);
this.label2.TabIndex = 3;
this.label2.Text = "迷 宫";
this.label2.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(376, 274);
this.Controls.Add(this.label2);
this.Controls.Add(this.button1);
this.Controls.Add(this.label1);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = " 迷 宫 问 题";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
public int wayout(int i,int j,int dd)
{
int count,k;
for(k=dd,count=0;(k<=7&&count<=1);k++)
{
if((i==(rows-2))&&(j==(columns-2)))
return -1;
if(maze[i+movei[k],j+movej[k]]==0)
{
nextd[count++]=k;
if(count==1)
{
nexti=i+movei[k];
nextj=j+movej[k];
}
}
}
return count;
}
//函数fork将分支点信息送入栈内
public void fork(int i,int j,int d)
{
int tempi,tempj,tempdir;
tempi=i;
tempj=j;
tempdir=d;
stki.Push (tempi);
stkj.Push (tempj);
stkdir.Push (tempdir);
}
//函数back执行回溯操作
public bool back (ref int ip,ref int jp,ref int dp)
{ int tempi,tempj,tempdir;
if (stki.Count==0&&stkj.Count==0&&stkdir.Count==0)
return false;
tempi=(int)stki.Pop();
tempj=(int)stkj.Pop();
tempdir=(int)stkdir.Pop();
ip=tempi;
jp=tempj;
dp=tempdir;
return true;
}
private void button1_Click(object sender, System.EventArgs e)
{
int i,j;
string a;
while(!stopmaze)
{
switch (wayout(curi,curj,d))
{
case -1:
stopmaze=true;
break;
case 0:
if(back(ref curi,ref curj,ref d)==false)
{
textBox1.Text ="本迷宫无解";
}
break;
case 2:
fork(curi,curj,nextd[1]); textBox1.Text ="本迷宫无解";
break;
case 1:
curi=nexti;
curj=nextj;
d=0;
maze[curi,curj]=8;
continue;
}
}
for (i=0;i<5;i++)
{
textBox1.AppendText("/n");
for(j=0;j<9;j++)
{
a = Convert.ToString(maze[i,j]);
textBox1.AppendText(a);
textBox1.AppendText(" ");
}
}
}
}
}