jjzjj

用栈求解迷宫问题的所有路径及最短路径程序(纯c语言)

hooty_ 2024-07-03 原文

参考了这个博客

学校作业,在各种地方搜了半天,看别人的要么就是有点错,要么就是很复杂用了不少我不知道的库,还要么就是只求了一条路径,还要么就是用了c++没学过。

写了半天,写出了一个应该是比较简单的方法,应该是还能优化,不过作业能跑就行,懒得搞了。有更好的想法,欢迎交流。

----------------------------------------------------------------------------------------

正文

讲讲思路吧,首先定义一下迷宫的方块

typedef struct {
	int i;//行
    int j;//列
    int di;//探索方向
}box;

再定义一下栈

typedef struct {
	box data[maxsize];
	int top;
}stack;//定义栈的类型

这里面主要的就是di探索方向

实现试探的代码如下采用了switch的方法

switch (di)//试探方块
			{
			case 0:a = i - 1, b = j; break;
			case 1:a = i, b = j + 1; break;
			case 2:a = i + 1, b = j; break;
			case 3:a = i, b = j - 1; break;
			}

如试探的方块是可以通过的那就入栈,要是所有方向都不行就退栈,回到上一个方块,以此类推,直到试探到方块是出口。同时为了防止重复经过方块,再入栈时把迷宫数组在这一点变成-1(0是路,1是墙)

比较关键的是怎么探查出所有的路径。

我的想法是在第一次找到出口时,在输出路径后,就直接退栈,再利用continue结束这次循环。达到回溯道路的作用。

退栈后回到上一个方块 ,换一个方向再继续试探,重复以上的过程即可。

再就是算最短路径,直接再找到出口的时候比较一下top指针就好了

if (s->top +1< min)//比较路径长度
			{
				min = s->top+1;//长度
				_min = count;//最短长度对应的第几条路
			}

完整代码如下

#include<stdio.h>
#define maxsize 100
int mg[6][6]={ {1,1,1,1,1,1},{1,0,0,0,1,1},
				  {1,0,1,0,0,1},{1,0,0,0,1,1},
				  {1,1,0,0,0,1},{1,1,1,1,1,1} };
//设置迷宫 1为墙,0为路
typedef struct {
	int i, j, di;
}box;//定义栈的元素
typedef struct {
	box data[maxsize];
	int top;
}stack;//定义栈的类型
void Initstack(stack*& s)//初始化栈
{
	s = new stack;
	s->top = -1;
}
bool push(stack*& s, box e)//压栈
{
	if (s->top == maxsize - 1)
		return false;
	s->top++;
	s->data[s->top] = e;
	return true;
}
bool pop(stack*& s, box &e)//出栈
{
	if (s->top == -1)
		return false;
	e = s->data[s->top];
	s->top--;
	return true;
}
bool gettop(stack*& s, box& e) //取栈顶元素
{
	if (s->top == -1)
		return false;
	e = s->data[s->top];
	return true;
}
bool mgpath(int x, int y, int xi, int yi)//寻找路径 起点坐标(x,y)终点坐标(xi,yi)
{
	int min = 100, _min=1;
	int i, j, di,count=1,k,a,b;
	int flag = 0;//有解的标志
	box e;
	bool find;
	stack* s;
	Initstack(s);//初始化栈
	e.i = x;//设置入口
	e.j = y;
	e.di = -1;
	push(s, e);
	mg[x][y] = -1;//入口设为-1防止重复走
	while (s->top != -1)//不为空栈时循环
	{
		gettop(s, e);//取栈顶方块e(i,j)
		i = e.i;
		j = e.j;
		di = e.di;
		if (i == xi && j == yi)//找到出口输出该路径
		{
			flag = 1;
			if (s->top +1< min)//比较路径长度
			{
				min = s->top+1;//长度
				_min = count;//最短长度对应的第几条路
			}
			printf("第%d条路径如下:\n", count++);
			for (k = 0; k <= s->top; k++)
				printf("(%d,%d)\t", s->data[k].i, s->data[k].j);
			printf("\n");
			pop(s, e);//回溯道路
			mg[e.i][e.j] = 0;
			continue;//结束当次循环
		}
		find = false;
		while (di < 4 && !find)//找下一个可走方块
		{
			di++;//初值为-1
			switch (di)//试探方块
			{
			case 0:a = i - 1, b = j; break;
			case 1:a = i, b = j + 1; break;
			case 2:a = i + 1, b = j; break;
			case 3:a = i, b = j - 1; break;
			}
			if (mg[a][b] == 0)
				find = true;//找到可走方块(a,b)
		}
		if (find)//找到
		{
			s->data[s->top].di = di;
			e.i = a;
			e.j = b;
			e.di = -1;
			push(s, e);//方块(a,b)入栈
			mg[a][b] = -1;//设为-1防止重复走
		}
		else //找不到
		{
			pop(s, e);
			mg[e.i][e.j] = 0;//恢复退栈方块
		}
	}
	if (flag == 1)
	{
		printf("最短路径为路径%d\n", _min);
		printf("最短路径长度为%d\n", min);
		return true;
	}
	delete(s);//释放栈
	return false;
}
int main()
{
	if (!mgpath(1, 1, 4, 4))
		printf("该迷宫问题没有解!\n");
	return 0;
}




结果示例

有关用栈求解迷宫问题的所有路径及最短路径程序(纯c语言)的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  5. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  6. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  7. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  8. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  9. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  10. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

随机推荐