数据结构 -最短路径dijkstra(迪杰斯特拉)算法讲解及代码实现

这篇具有很好参考价值的文章主要介绍了数据结构 -最短路径dijkstra(迪杰斯特拉)算法讲解及代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        迪杰斯特拉算法是一种广义的贪心算法,求出局部最优解,再去求全局最优解

图文讲解:

举例图:(起始点为1)

dijkstra代码,数据结构,算法,数据结构,贪心算法,迪杰斯特拉

辅助数组:

s:记录了目标顶点到其他顶点的最短路径是否求得(求得为1,否则为0)

p:目标顶点到其他顶点的最短路径的前驱节点

(如,求得1->7->5的最短路径,那么5的前驱节点为7)

d:记录目标顶点到其他顶点最短距路径的长度 

首先利用二维数组构建图中各个顶点的辅助数组的初始化关系:

dijkstra代码,数据结构,算法,数据结构,贪心算法,迪杰斯特拉

初始化的解析:初始化只知道目标顶点:顶点1到自己的最短路径也就是0,所以s1为1其余没有求得标记为0,p中目标顶点v1到1 3 4 5顶点都没有弧也就是没有目标顶点到此节点的前驱节点设为-1,

d为目标顶点v1到与他有弧的节点的弧长度(权重),没有弧的则设置为无穷(32767) 

 步骤:(x集合为记录已经找到最短路径的节点,最初x:v1(目标节点))

1.每次从d中找到最小的数,并找到其节点下标,将此节点的s标记为1意味已找到目标节点到此节点的最短路径,再把此节点加入到我们的x集合当中。

2.把已经找到的最小路径的节点当作中专点,判断目标顶点到当前节点的路径+当前节点到其他节点的路径是都小于目标节点到其他节点的路径长度,如过小于则更新目标节点的长度。

(如v1-v3为无穷,v1-v2-v3为22,小于无穷所以把v1-v3的路径改为22:d2为22)

3.重复1,2的操作直到x集合标记完所有节点(s数组元素全部为1)。

代码实现:

#include <stdio.h>
#include <stdlib.h>
#define MAX 32767
typedef struct Graph
{
	char* vexs;//顶点
	int** arcs;//边(用二级指针存放存放边的一级指针,一级指针存放边)
	int vexsNum;//顶点的个数
	int arcsNum;//边的个数
}Graph;

Graph* initGraph(int vexNum)
{
	Graph* G = (Graph*)malloc(sizeof(Graph));
	G->vexs = (char*)malloc(sizeof(char)*vexNum);
	G->arcs = (int**)malloc(sizeof(int*)*vexNum);
	for (int i = 0; i < vexNum; i++)
	{
		G->arcs[i] = (int*)malloc(sizeof(int) * vexNum);
	}
	G->vexsNum = vexNum;
	G->arcsNum = 0;
	return G;
}

void crativeGraph(Graph* G, char* vexs, int* arcs)
{
	for (int i = 0; i <G->vexsNum; i++)
	{
		G->vexs[i] = vexs[i];//(Graph中的顶点数组存放顶点的“名字”)
	for (int j = 0; j < G->vexsNum; j++)
		{
			G->arcs[i][j] = *(arcs + i * G->vexsNum + j);//二维数组加一个数表示第i+1个元素(相当于把二维数组全排成一行)                                                            
			if (G->arcs[i][j] > 0 && G->arcs[i][j] != MAX)
				G->arcsNum++;//统计边的个数(二维数组中有边则元素为1) //这里的图为带权重的图所以再统计边的时候二维数组元素既要大于0也要不为无穷                                                                  
		}
	}
	G->arcsNum /= 2;//(二维数组计算了两次边的次数)
}
//DFS深度优先遍历的访问
void DFS(Graph* G, int* visited, int index)
{
	if (index==4)
	{
		printf("%c ", G->vexs[index]);
		visited[index] = 1;
	}
	else
	{
		printf("%c->", G->vexs[index]);//先打印出顶点
		visited[index] = 1;//再把访问过的顶点做标记
	}
	for (int i = 0; i < G->vexsNum; i++)
	{
		if (G->arcs[index][i] > 0 && G->arcs[index][i] != MAX && !visited[i])//因为为带权重的图所以dfs访问的时候边的条件也是要满足>0且!=无穷两节点才有边
		{
			DFS(G, visited, i);
		}
	}
}
void dijkstra(Graph* G,int index)
{//准备辅助数组
	int* s = (int*)malloc(sizeof(int) * G->vexsNum);//记录最短路径是否求得(1是,0否)
	int* p = (int*)malloc(sizeof(int) * G->vexsNum);//记录目标顶点到其他顶点的最短路径的前驱节点
	int* d = (int*)malloc(sizeof(int) * G->vexsNum);//记录了目标顶点到其他顶点的最短路径长度
	//初始化辅助数组
	for (int i = 0; i < G->vexsNum; i++)
	{//最初我们只知道目标顶点到自己的最短路径
		if (i == index)
			s[i] = 1;
		else
			s[i] = 0;
	}
	for (int i = 0; i < G->vexsNum; i++)
	{
		if (G->arcs[index][i] > 0 && G->arcs[index][i] != MAX)
			p[i] = index;//如果节点与目标节点有弧则将此节点的前驱节点设为目标节点

		else
			p[i] = -1;
	}
	for (int i = 0; i < G->vexsNum; i++)
	{
		if (G->arcs[index][i] > 0 && G->arcs[index][i] != MAX)
			d[i] = G->arcs[index][i];
		else
			d[i] = MAX;
		if (i == index)
			d[i] = 0;
	}
	printf("最初图 的辅助数组\n");
	for (int i = 0; i < G->vexsNum; i++)
	{
		printf("%d %d %d\n", s[i],p[i],d[i]);//三个数组是竖着输出的
	}
	
	for (int i = 0; i < G->vexsNum - 1; i++)
	{
		int index = getMin(d,s,G);
		s[index] = 1;//将s数组数组元素改为1意味着:已经找到起始节点到此节点的最短路径
		for (int j = 0; j < G->vexsNum; j++)
		{//将返回的节点作为中转点
			if (!s[j] && d[index] + G->arcs[index][j] < d[j])//判断v1到中专点的距离+到其他节点的距离和是否小于v1到其他节点的距离
			{
				d[j] = d[index] + G->arcs[index][j];//如果小于则更新v1-此节点的最短路径
				p[j] = index;//并且将此节点的前驱节点改为中转点
			}
		}
	}
	printf("最短路径的图的辅助数组\n");
	for (int i = 0; i < G->vexsNum; i++)
	{
		printf("%d %d %d\n", s[i], p[i], d[i]);
	}
}
int getMin(int* d, int* s, Graph* G)
{
	int min = MAX;
	int index = 0;
	//找与起始节点有弧的且弧长度最小(权重最短)的节点,并且返回此节点的下标
	for (int i = 0; i < G->vexsNum; i++)
	{
		if (!s[i] && d[i] < min)
		{
			min = d[i];
			index = i;
		}
	}
	return index;
}
int main()
{
	Graph* G = initGraph(7);
	//创建深度优先遍历的时候判断该顶点是否被访问的数组
	int* visited = (int*)malloc(sizeof(int) * G->vexsNum);
	for (int i = 0; i < G->vexsNum; i++)
	{
		visited[i] = 0;//先把每个元素都设为0,当被访问过的时候就改变元素的值
	}
	//提前根据图的数创建出符合其边的关系的二位数组
	int arcs[7][7] =
	{
		0,12,MAX,MAX,MAX,16,14,
		12,0,10,MAX,MAX,7,MAX,
		MAX,10,0,3,5,6,MAX,
		MAX,MAX,3,0,4,MAX,MAX,
		MAX,MAX,5,4,0,2,8,
		16,7,6,MAX,2,0,9,
		14,MAX,MAX,MAX,8,9,0
	};
	crativeGraph(G, "1234567", (int*)arcs);//节点的“名字”
	DFS(G, visited, 0);//这里我们把目标节点定位v1所以index传0
	dijkstra(G, 0);
	printf("\n");
	return 0;
}

“不看广告看疗效”

(辅助数组我们都是竖着输出的)

dijkstra代码,数据结构,算法,数据结构,贪心算法,迪杰斯特拉

最后我们可以通过辅助数组找到目标节点到任何节点的最短路径

eg:目标节点-v5

1.先找v5的前驱节点v6,路径为18

2.找v6的前驱节点为v1,路径为16

所以v1-v5的路径为v1-v6-v5,最短路径为18+16=34. 文章来源地址https://www.toymoban.com/news/detail-670552.html

到了这里,关于数据结构 -最短路径dijkstra(迪杰斯特拉)算法讲解及代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构--迪杰斯特拉(Dijkstra)算法

    生活封锁了我们,只要我们的心不死,生活便永远不是一汪死水,而我们,依然会绽放最美的姿态。 戴克斯特拉算法(英语:Dijkstra’s algorithm),又称迪杰斯特拉算法、Dijkstra算法,是由荷兰计算机科学家艾兹赫尔·戴克斯特拉在1956年发现的算法,并于3年后在期刊上发表。

    2024年02月04日
    浏览(51)
  • 大话数据结构-迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd)

      最短路径,对于图来说,是两顶点之间经过的边数最少的路径;对于网来说,是指两顶点之间经过的边上权值之和最小的路径。路径上第一个顶点为源点,最后一个顶点是终点。   以如下无向图为例:   我们来计算下标为0的顶点,到其他顶点的最短路径,首先定义

    2024年02月06日
    浏览(41)
  • 【数据结构】最短路径算法实现(Dijkstra(迪克斯特拉),FloydWarshall(弗洛伊德) )

    最短路径问题 :从在带权有向图G中的某一顶点出发,找出一条通往另一顶点的最短路径,最短也就是沿路径各边的权值总和达到最小。 单源最短路径问题:给定一个图G = ( V , E ) G=(V,E)G=(V,E),求源结点s ∈ V s∈Vs∈V到图 中每个结点v ∈ V v∈Vv∈V的最短路径 针对一个带权

    2024年02月04日
    浏览(50)
  • C语言 最短路径 迪杰斯特拉(Dijkstra)算法

    迪杰斯特拉(Dijkstra)算法是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中单源最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最

    2024年02月03日
    浏览(43)
  • 大二数据结构实验(迪杰斯特拉最短路径)

    大二数据结构实验,有详细批注,代码可以直接运行,希望可以给大家提供到帮助。 实验目的 掌握图的邻接矩阵的存储定义。 掌握图的最短路径(Dijsktra)算法的实现。 实验内容 设计校园平面图,所含景点不少于8个。以图中顶点表示学校内各景点,存放景点的名称、景点

    2024年02月12日
    浏览(42)
  • java实现迪杰斯特拉(Dijkstra)算法求解最短路问题

    迪杰斯特拉(Dijkstra)算法是由荷兰计算机科学家狄克斯特拉于1959年提出的。是寻找从一个顶点到其余各顶点的最短路径算法,可用来解决最短路径问题。 迪杰斯特拉算法采用贪心算法的策略,将所有顶点分为已标记点和未标记点两个集合,从起始点开始,不断在未标记点中寻

    2024年02月12日
    浏览(40)
  • MATLAB轻松绘制地图路线——Dijkstra(迪杰斯特拉)算法最短路径规划

    利用MATLAB绘制地图需要三个基本数据: 节点 节点坐标 节点间相通的路线 以11B交通巡警平台调度问题中的A区数据为例: (数据及工程文件下载链接见文末) Demo1: 可通过已知节点的坐标,计算出各节点之间的距离,有Matlab基础的同学可以尝试Demo2, 也可通过Excel自行实现;

    2023年04月21日
    浏览(49)
  • 迪杰斯特拉(Dijkstra's )算法——解决带权有向无向图最短路径

    迪杰斯特拉算法(Dijkstra\\\'s Algorithm),又称为狄克斯特拉算法,是一种用于解决带权重有向图或无向图最短路径问题的算法。该算法由荷兰计算机科学家艾兹赫尔·狄克斯特拉在1956年发明,是一种广泛应用于网络路由和其他领域的算法。 在 2001 年的一次采访中,Dijkstra 博士透露

    2024年02月03日
    浏览(48)
  • 使用omp并行技术加速最短路径算法-迪杰斯特拉(Dijkstra)算法(记录最短路径和距离)

    原理: Dijkstra算法是解决**单源最短路径**问题的**贪心算法** 它先求出长度最短的一条路径,再参照该最短路径求出长度次短的一条路径     直到求出从源点到其他各个顶点的最短路径。 首先假定源点为u,顶点集合V被划分为两部分:集合 S 和 V-S。 初始时S中仅含有源点u,

    2024年02月10日
    浏览(49)
  • 数据结构第13周 :( 迪杰斯特拉最短路径 + 弗洛伊德求最短路径 + 欧拉回路 + Invitation Cards)

    【问题描述】 在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。 在常用的单源点最短路径算法中,迪杰斯特拉算法是最为常用的一种,是一种按照路径长度递增的次序产生最短路径的算法。 在本题中,读入一个有向图

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包