数据结构之有向网邻接矩阵Dijkstra实现源点至其余各顶点最短路径

本文详细介绍了如何利用Dijkstra算法,在有向图的邻接矩阵表示中求解从源点到所有其他顶点的最短路径问题。通过对图的遍历和路径权重更新,确保找到最短路径。该方法适用于解决图论中的路径寻找问题。

#include<iostream>
using namespace std;
#define MAXVEX 100
#define INFINITY 65535
typedef char VNode;
typedef int ANode;
typedef struct MGraph
{
	VNode Vex[MAXVEX];
	ANode Arc[MAXVEX][MAXVEX];
	int Vnums;
	int Anums;
}MGraph;

void CreateNGraph(MGraph &G)
{
	int i, j, k;
	ANode w;
	cin >> G.Vnums >> G.Anums;
	for (i = 0; i < G.Vnums; ++i)
		cin >> G.Vex[i];
	for (i = 0; i < G.Vnums; ++i)
		for (j = 0; j < G.Vnums; ++j)
			G.Arc[i][j] = INFINITY;
	for (k = 0; k < G.Anums; ++k)
	{
		cin >> i >> j >> w;
		if (i != j)
		{
			G.Arc[i][j] = w;
			G.Arc[j][i] = G.Arc[i][j];
		}
	}
}

int LocateVex(MGraph G, VNode v)
{
	int i;
	for (i = 0; i<G.Vnums; ++i)
		if (G.Vex[i] == v)
			return i;
	return -1;
}

VNode GetVex(MGraph G, int i)
{
	if (i >= G.Vnums || i < 0)
		exit(-1);
	return G.Vex[i];
}

bool PutVex(MGraph &G, VNode v, VNode value)
{
	int i;
	i = LocateVex(G, v);
	if (i < 0)
		return false;
	G.Vex[i] = value;
	return true;
}

int FirstAdjvexN(MGraph G, VNode v)
{
	int i, k;
	k = LocateVex(G, v);
	for (i = 0; i < G.Vnums; ++i)
		if (G.Arc[k][i] != INFINITY)
			return i;
	return -1;
}

int NextAdjvexN(MGraph G, VNode v, VNode w)
{
	int i, k1, k2;
	k1 = LocateVex(G, v);
	k2 = LocateVex(G, w);
	for (i = k2 + 1; i < G.Vnums; ++i)
		if (G.Arc[k1][i] != INFINITY)
			return i;
	return -1;
}

void InsertVexN(MGraph &G, VNode v)
{
	int i;
	for (i = 0; i <= G.Vnums; ++i)
	{
		G.Arc[i][G.Vnums] = INFINITY;
		G.Arc[G.Vnums][i] = INFINITY;
	}
	G.Vnums++;
}

bool VisitTag[MAXVEX];

void Visit(VNode v)
{
	cout << v << " ";
}

void DFS(MGraph G, int i)
{
	int j;
	Visit(G.Vex[i]);
	VisitTag[i] = true;
	for (j = FirstAdjvexN(G, G.Vex[i]); j >= 0; j = NextAdjvexN(G, G.Vex[i], G.Vex[j]))
		if (!VisitTag[j])
			DFS(G, j);
}

void DFST(MGraph G)
{
	int i;
	for (i = 0; i < G.Vnums; ++i)
		VisitTag[i] = false;
	for (i = 0; i < G.Vnums; ++i)
		if (!VisitTag[i])
			DFS(G, i);
	cout << endl;
}

/******************************************************/
#define QSIZE MAXVEX
typedef struct Queue
{
	int *pBase;
	int Front;
	int Rear;
}Queue;

void InitQueue(Queue &Q)
{
	Q.pBase = new int[QSIZE];
	Q.Front = 0;
	Q.Rear = 0;
}

bool QueueFull(Queue Q)
{
	if ((Q.Rear + 1) % QSIZE == Q.Front)
		return true;
	else
		return false;
}

bool QueueEmpty(Queue Q)
{
	if (Q.Rear == Q.Front)
		return true;
	else
		return false;
}

void EnQueue(Queue &Q, int i)
{
	if (QueueFull(Q))
		return;
	Q.pBase[Q.Rear] = i;
	Q.Rear = (Q.Rear + 1) % QSIZE;
}

void DeQueue(Queue &Q, int &i)
{
	if (QueueEmpty(Q))
		return;
	i = Q.pBase[Q.Front];
	Q.Front = (Q.Front + 1) % QSIZE;
}

void BFST(MGraph G)
{
	int i, j;
	Queue Q;
	InitQueue(Q);
	for (i = 0; i < G.Vnums; ++i)
		VisitTag[i] = false;
	for (i = 0; i < G.Vnums; ++i)
	{
		if (!VisitTag[i])
		{
			Visit(G.Vex[i]);
			VisitTag[i] = true;
			EnQueue(Q, i);
			while (!QueueEmpty(Q))
			{
				DeQueue(Q, i);
				for (j = FirstAdjvexN(G, G.Vex[i]); j >= 0; j = NextAdjvexN(G, G.Vex[i], G.Vex[j]))
				{
					if (!VisitTag[j])
					{
						Visit(G.Vex[j]);
						VisitTag[j] = true;
						EnQueue(Q, j);
					}
				}

			}
		}
	}
	cout << endl;
}

/*******************************************************/

typedef int PathArc[MAXVEX];//存储最短路径下标
typedef int ShortPathTable[MAXVEX];//存储出发点到各点路径的权值和

void ShortestPath_Dijkstra(MGraph G, int m, PathArc P, ShortPathTable D)
{
	int i, j, k, min;
	bool final[MAXVEX];//etc:final[i]==true,表示求得了m至i的最短路径
	for (i = 0; i < G.Vnums; ++i)
	{
		final[i] = false;
		D[i] = G.Arc[m][i];
		P[i] = 0;
	}
	D[m] = 0;
	P[m] = -1;//显然没有至原始出发点的路径,故下标设-1
	final[m] = true;//原始出发点
	for (i = 1; i < G.Vnums; ++i)
	{//循环一次求得原始出发点至某一顶点的最短路径
		min = INFINITY;//暂时设置,以淘汰对应非邻接点
		for (j = 0; j < G.Vnums; ++j)
		{
			if (!final[j] && D[j]<min)
			{
				k = i;
				min = D[j];
			}
		}//寻得距离当前顶点更近的顶点
		final[k] = true;//求得出发点至k位置顶点的最短路径并标记之
		for (j = 0; j < G.Vnums;++j)
		{
			if (!final[j] && (min + G.Arc[k][j]) < D[j])
			{//寻找到了更短的路径
				D[j] = min + G.Arc[k][j];//更新出发点至j点的当前路径长度和
				P[j] = k;//值更新为k
			}
		}
	}
}

void PrintShortestPathDIJ(MGraph G,int m)
{
	PathArc P;
	ShortPathTable D;
	int i, j;
	ShortestPath_Dijkstra(G,m, P, D);
	for (i = G.Vnums-1; i >= 0; i--)
	{
		j = i;
		while (P[j] != -1 && P[j] != 0)
		{
			cout << "v" << j << "<-" << "v" << P[j] << "  ";
			j = P[j];
		}
		cout << "v" << j << "<-" << "v" << m << "  ";
		cout << endl;
	}
	cout << endl;
}

int main(void)
{
	MGraph G;	
	CreateNGraph(G);
	PrintShortestPathDIJ(G, 2);
	DFST(G);
	BFST(G);
	return(0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值