算法初学者(图的存储)链式前向星

知识储备:概念,存储,遍历,最短路,最小生成树,拓扑排序-关键路径

图的存储:邻接矩阵,邻接表,十字链表,多重邻接表,边集数组

其中:邻接表,十字链表,多重邻接表是基于链表实现的,涉及到指针,代码操作复杂,且容易出现空指针,野指针的bug。

其中,刷题时常用的是邻接矩阵和邻接表,但是因为上述原因,需要对邻接表的代码实现改进。

邻接矩阵和边集数组是基于数组的,按照上一篇讲解实现即可。

邻接表:一维数组存点---顶点数组。每个顶点的所有邻接点构成一个链表,挂在顶点数组后。

邻接表存无权图,可以直接将邻接表转化成二维数组,a[x][i]=y;顶点x的第i个邻接点是顶点y,即顶点x的第i条出边是边<x,y>。注意和邻接矩阵的区分。

不带权的邻接表转换为二维数组并且深度优先遍历代码如下

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
vector<vector<int>>adj;
int n, m;//n个点,m条边
int v[105];
void DFS(int u) {
	if (v[u] == 1)return;
	printf("%d ", u);
	v[u] = 1;
	for (int i = 0; i < adj[u].size(); i++) {
		int v1 = adj[u][i];
		if (v[v1] == 0) {
			DFS(v1);
		}
	}
}
int main() {
	int x, y;
	scanf("%d %d", &n, &m);
	adj.resize(n + 1);
	for (int i = 1; i <= m; i++) {
		scanf("%d %d", &x, &y);
		adj[x].push_back(y);//把y加到x那行
		adj[y].push_back(x);//把x加到y那行
	}
	for (int i = 1; i <= n; i++) {
		if (v[i] == 0) {
			DFS(i);
		}
	}

	return 0;
}
//4 5
//1 2
//1 4
//2 3
//2 4
//3 4

带权的邻接表转换为二维数组代码如下(静态链表)(边集数组)----链式前向星

链式前向星的两种结构

1边集数组:edge[],edge[i]表示第i条边,存储边的信息:to,w,next,其中next不再是指针而是边的编号。

2头节点数组:head[],head[x]存以x为起点的第一条边的下标指:在edge[]中的下标。初始时head[]数组全部初始化为-1,即认为没有边。

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
struct Edge {
	int to;//终点
	int w;//边权
	int next;//具有相同起点的下一条边
}e[10005];
int head[105];
int n, m;//n点 m边
int cut;//实际边的数目,边的编号
void add(int x, int y, int w) {
	e[cut].to = x;
	e[cut].w = w;
	e[cut].next = head[x];
	head[x] = cut;
	cut++;//为下一条边
}
int v[105];//用来记录有没有被遍历过
void DFS(int x) {
	if (v[x] == 1)return;
	printf("%d ", x);
	v[x] = 1;
	for (int i = head[x]; i != -1; i = e[i].next) {
		//i是边的编号,y才是终点(他的邻接点)--接下来遍历邻接点
		int y = e[i].to;
		if (v[y] == 0) {
			DFS(y);
		}
	}
}
int main() {
	int x, y, w;
	scanf("%d %d", &n, &m);
	memset(head, -1, sizeof(head));
	cut = 0;
	for (int i = 0; i < m; i++) {
		scanf("%d %d %d", &x, &y, &w);
		add(x, y, w);
		add(y, x, w);//无向图建边
	}
	for (int i = 1; i <= n; i++) {
		if (v[i] == 0) {
			DFS(i);
		}
	}
	return 0;
}
//4 5
//1 2 5
//1 4 3
//2 3 8
//2 4 12
//3 4 9

结构体数组可以分解成三个数组

链式前向星DFS遍历时间复杂度(v+e)--点+边

相关推荐
计算机小白一个19 分钟前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^1 小时前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
黑不溜秋的1 小时前
C++ 设计模式 - 策略模式
c++·设计模式·策略模式
大数据追光猿3 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!3 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉3 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生3 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴3 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing3 小时前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode
qy发大财3 小时前
加油站(力扣134)
算法·leetcode·职场和发展