用深度遍历查找两点之间的最小路径算法

11 篇文章 0 订阅
10 篇文章 1 订阅

abe7b06557424c44911009eb8995f6bc.png

 0ed6a8e999324779b8a699abf853f71c.png

 因为这是两点之间的最小路径问题(即单源最短路径问题)所以用深度或广度遍历进行查找较方便。

采用深度遍历查找(代码+解析)如下:结合代码进行解析和结合图进行理解较容易。

#include <stdio.h>
#include <stdlib.h>
#define MAX 100
//not_c 表示的是没有关系的值 
#define not_c 10000 
//图的结构 
struct Chart{
	int bian_sum;
	int spot_sum;
	int connection[MAX][MAX];
};
typedef struct Chart *tu;
//边的结构 
struct Bian{
	int left,right;
	int value;
};
typedef struct Bian *bian;

//访问标志
int visit[MAX]; 

//最短的路径以及从哪到哪个顶点 
int minpart= not_c;//默认是not_c当没有找到最小路径时即两个点没有关系时的值 
int spot_left;
int spot_right; 

void chazhao(tu chart,int now_spot,int now_value);
tu creater(int dian);
 


int main(){
	int dian;
	printf("请输入顶点的个数:");
	scanf("%d",&dian);
	tu chart;
	//初始化图:即创建一个没有边的图 
	chart=creater(dian);
	//创建边
	bian tran;
	tran=(bian)malloc(sizeof(struct Bian));
	//创建有边的图,该题是有有向图 
	printf("请输入边的个数:");
	scanf("%d",&chart->bian_sum);
	for(int i=0;i<chart->bian_sum;i++){
		printf("请输入从哪个点到哪个点和之间的权值:");
		scanf("%d%d%d",&tran->left,&tran->right,&tran->value);
		 //创建
		 chart->connection[tran->left][tran->right]=tran->value; 
	} 
	printf("请输入你要查找哪两个顶点的最短的路径:");
	scanf("%d%d",&spot_left,&spot_right);
	//将开始位置进行标记
	 visit[spot_left]=1;//因为执行函数里面不是到某个结点就进行标记 
	//第一次进入的是开始的位置和当前走过的权值为0 
	chazhao(chart,spot_left,0);//利用深度优先遍历执行。作为参数进入的是图和当前的结点和走到当前结点的权值
	 //执行结束将查找到的最小的路径进行输出
	 printf("从%d到%d的最小的权值为:%d",spot_left,spot_right,minpart) ;
}
tu creater(int dian){
	tu head;
	head=(tu)malloc(sizeof(struct Chart));
	head->bian_sum=0;
	head->spot_sum=dian;
	for(int i=1;i<=dian;i++){
		for(int j=1;j<=dian;j++){
			head->connection[i][j]=not_c;
		}
		head->connection[i][i]=0;//我们讲的图斗是简单图(即自己和自己是没有边的)
		 //赋0表示是自己的位置 
	}
	return head;
}
//用深度优先遍历进行查找
void chazhao(tu chart,int now_spot,int now_value){
	if(now_value>=minpart)//这里是判断走到当前结点的权值有没有已经大于我上一次找到的最小权值。如果已经大于等于说明再往该路径走阴茎没有意义 
	return;//不执行下面的程序 
	 //判断是不是走到我要找的结点的位置了
	 if(now_spot==spot_right){
	 	if(minpart>now_value){
	 		minpart=now_value;
	 		return;//不执行下面程序 
		 }
	 } 
	 for(int i=1;i<=chart->spot_sum;i++){
	 	if(visit[i]==0&&chart->connection[now_spot][i]!=0&&chart->connection[now_spot][i]!=not_c){
	 		visit[i]=1;//表示当前位置 
	 		//调用的权值是上一次走到当前位置的权值加上从当前位置走到下一次位置的权值 
	 		chazhao(chart,i,now_value+chart->connection[now_spot][i]) ;
			//执行完后变为没有访问过的 
			visit[i]=0;
			//一定要理解这里为什么要变为没有访问过的;
			//理解:将下一个结点标志为没有访问过的:
			//因为我们要找进行各种路径的寻找,只有再执行完后标志为没有访问过的才能在下次时也能访问该结点(画图即可理解) 
		 }
	 }
}

结果如下:

c0639e2749f5465c8258e8b44542d53c.png

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小丞啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值