每日算法:Dijkstra的邻接表和邻接矩阵实现

日期:2023.10.12

第四天

邻接矩阵:

/*
	邻接矩阵实现法:
	1.不要忘记可能在未被访问过的集合中,找不到最小距离的点,这时函数应该直接返回;
	2. 时间复杂度为 O(V*(V+V)) = O(V*V) 
	 
*/

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1000;	//最大顶点数
const int INF = 0x3f3f3f3f;
bool vis[N] = {0};	//	标记已访问过的点
int d[N];	//存储每个点到起点的距离
int G[N][N];
int n;

void Dijkstra(int s) {	//传入起点编号

	//初始时,把起点以外的所有点到起点距离都设置为无穷大 
	memset(d, 0x3f, sizeof(d));
	d[s] = 0;
	
	//默认G图中无边的话,边长是INF 
	
	
	for(int i = 0; i < n; i++) {	//已访问过的点的集合到达n个点时,循环结束 
		//1.找到未访问过的顶点中,距离起点最小的值
		int u = -1, MIN = INF;	//u记录最小距离的顶点编号,MIN记录最小距离的值 
		//这个循环遍历所有点,找到最小距离的点 
		for(int j = 0; j < n; j++) { 
			if(vis[j] == 0 && d[j] < MIN) {
				u = j;
				MIN = d[j];
			}
		} 
		//注意可能u可能还是-1,表示找不到小于INF的d[u],说明剩下的顶点和起点S不连通
		if(u == -1) return ;
		vis[u] = 1;
		
		//在未被访问过的点中,找与u相连的点 ,更新它到起点的距离; 
		for(int v = 0; v < n; v++) {
			if(G[u][v] != INF && vis[v] == 0) {
				d[v] = min(d[v], d[u] + G[u][v]);
			}
		} 
		
	}
	
	
}
 
int main(void) {
	
	return 0;
}

 邻接表:

/*
	揣摩一下:
		存储一条边时,就是两个顶点,一条边长;
		邻接矩阵存储的话,顶点信息就是下表,然后元素的值是边长;
		邻接表存储: Adj[u][i]的i 是没有用处的,只能选择存储信息在Adj[u][i]的值,
		这个值就是顶点u相连的顶点编号,所以如何还需要存储边长,邻接表的元素就得是结构体;
		
		当需要存储图的边长信息时,邻接表的元素需要是结构体 
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 100010;//最大顶点数 
struct Node {
	int v;	//顶点编号 
	int dis;	//边权 
}; 
vector<Node> Adj[N];
bool vis[N] = {0};
int d[N];
int n;

void Dijkstra(int s) {
	memset(d, 0x3f, sizeof(d));
	d[s] = 0;
	
	for(int i = 0; i < n; i++) {
		
		int u = -1, MIN = INF;
		for(int j = 0; j < n; j++) {
			if(vis[j] == 0 && d[j] < MIN) {
				u = j;
				MIN = d[j];
			}
		}
		if(u == -1) return ;
		//更新和u相连的点的最短距离
		for(int j = 0; j < Adj[u].size(); j++) {
			int v = Adj[u][j].v;
			if(vis[v] == 0) {
				d[v] = min(d[v], d[u] + Adj[u][v].dis);
			}
		} 
		
	}
} 

int main(void) {
	
	return 0;
}

注意:

1.邻接表存储图时,如果需要存储边权,就得以结构体为链表元素;

2.邻接表的内层循环的第二个循环,执行n次,刚好遍历完所有的边,所以复杂度是O(E),所以总时间复杂度是O(N*N+E);

3.算法第一步是找到不在集合S内的,距离起点最近的点,这个点可能找不到,代表剩下的所有点与起点不连通,需要特判一下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

前路漫漫亦灿灿上岸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值