数据结构实验---Dijsktra算法求最短路径

在代码中有其他需求可自行按备注更改,本代码是学校实验任务,参照课本及网上资料以及自己更改编写完成。

实验内容:输入图的顶点数、边数以及边,求某个顶点到各个顶点的最短路径。

该实验中输入的v0点即为要求的某个顶点,在输入顶点字符信息的地方,只是简单的将字符信息转换为数字信息,在代码中还可对其进行优化。

1、picture.cpp文件

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include "picture.h"

using namespace std;

Status LocateVex(AMGraph G, VerTexType u)
{
	int i;
	for (i = 0; i < G.vexnum; ++i)
	{
		if (G.vexs[i] == u)
			return i;				// 找到顶点值为u的位置,返回该位置在顶点表中的索引 i
	}
	return ERROR;					// 没找到,返回错误码
}

Status CreateDN(AMGraph& G)			//采用邻接矩阵表示法,创建有向网G
{
	int i, j, k, w;
	VerTexType v1, v2;				//v1、v2表示点的位置、w表示该点权值
	cout << "输入总顶点数:";
	cin >> G.vexnum;				//输入总顶点数、总边数
	cout << "输入总边数:";
	cin >> G.arcnum;

	cout << "依次输入顶点名称:";
	for (i = 0; i < G.vexnum; ++i)	//依次输入点的信息
		cin >> G.vexs[i];

	for (i = 0; i < G.vexnum; ++i)	//初始化邻接矩阵、边的权值	均置为极大值MaxInt
		for (j = 0; j < G.vexnum; ++j)
			G.arcs[i][j] = MaxInt;

	for (k = 0; k < G.arcnum; ++k)	//构建邻接矩阵
	{
		cout << "输入一条边的起点、终点及权值:";
		cin >> v1 >> v2 >> w;		//输入一条边依附的顶点及权值
		i = LocateVex(G, v1);
		j = LocateVex(G, v2);		//确定v1、v2在G中的位置,即顶点数组下标
		if (i == ERROR || j == ERROR)
		{
			cout << "顶点不存在!" << endl;
			return ERROR;
		}
		G.arcs[i][j] = w;			//边<v1,v2>的权值置为w 对称边<v2,v1>的权值为w
	}
	return OK;
}
//用Dijkstra算法求有向网的v0顶点到其余顶点的最短路径
void ShortestPath_DIJ(AMGraph G, int v0, int *D, int *Path)
{
	int n, v, i, min, w, max, m;
	int S[20];
	n = G.vexnum;					//n为G中顶点的个数
	for (v = 0; v < n; ++v)			//n个顶点依次初始化
	{
		S[v] = false;				//S初始为空集
		D[v] = G.arcs[v0][v];		//将v0到各个终点的最短路径长度初始化为弧上的权值
		if (D[v] < MaxInt)			//如果v0和v之间有弧,则将v的前驱置为v0
			Path[v] = v0;
		else						//如果v0和v之间无弧,则将v的前驱置为-1
			Path[v] = -1;
	}
	S[v0] = true;					//将v0加入S
	D[v0] = 0;						//源点到源点的距离为0
	/*-----初始化结束,开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集-----*/
	for (i = 1; i < n; ++i)			//对其余n-1个顶点,依次进行计算
	{
		min = MaxInt;
		for (w = 0; w < n; ++w)
			if (!S[w] && D[w] < min)
			{
				v = w;
				min = D[w];			//选择一条当前的最短路径,终点为v
			}
		S[v] = true;				//将v加入S
		for (w = 0; w < n; ++w)		//更新从v0出发到集合V-S上所有顶点的最短路径长度
			if (!S[w] && (D[v] + G.arcs[v][w] < D[w]))
			{
				D[w] = D[v] + G.arcs[v][w];		//更新D[w]
				Path[w] = v;					//更新w的前驱为v
			}
	}
}

2、picture.h文件

#pragma once
#ifndef PICTURE_H
#define PICTURE_H

typedef int Status;
#define	OK		1
#define ERROR	-1

#define swap(a, b)	{a = a + b; b = a - b; a = a - b;}

//-------图的邻接矩阵存储表示--------//
#define MaxInt  32767       //表示极大值,即∞
#define MVNum   100         //最大顶点数     
typedef char VerTexType;	//假设顶点的数据类型为字符型
typedef int ArcType;		//假设边的权值类型为整型
typedef struct
{
	VerTexType vexs[MVNum];		//顶点表
	ArcType arcs[MVNum][MVNum];	//邻接矩阵
	int vexnum, arcnum;			//图的当前点数和边数
}AMGraph;

Status CreateDN(AMGraph& G);			//采用邻接矩阵表示法,创建有向网G
Status LocateVex(AMGraph G, VerTexType u);
void ShortestPath_DIJ(AMGraph G, int v0, int* D, int* Path);

#endif 

3、main.cpp文件

#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <iomanip>
#include "picture.h"

using namespace std;

void show(AMGraph G, int* D, int* Path) 
{
	for (int i = 0; i < G.vexnum; ++i) 
	{
		if (D[i] == MaxInt) 
		{
			cout << "从v0到 " << G.vexs[i] << " 点的路径不存在" << endl;
		}
		else 
		{
			cout << "从v0到 " << G.vexs[i] << " 点的最短路径为:" << G.vexs[i];
			int pre = Path[i];
			while (pre != -1) 
			{
				cout << " <- " << G.vexs[pre];
				pre = Path[pre];
			}
			cout << ",长度为:" << D[i] << endl;
		}
	}
}

int main()
{
	int D[10];
	int Path[20];
	AMGraph G;
	CreateDN(G);
	cout << "v0到各点的最短路径(输入v0):";
	int v0;
	char v01;
	cin >> v01;
	for (v0 = 0; v0 < G.vexnum; ++v0)
	{
		if (G.vexs[v0] == v01)
			break;
	}
	ShortestPath_DIJ(G, v0, D, Path);
	show(G, D, Path);
	return 0;
}

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

慢慢丶丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值