定义: 邻接矩阵是一个二维数组,其中的元素表示图中顶点间是否存在边。对于无向图,矩阵是对称的。
空间复杂度: 对于有V
个顶点的图,邻接矩阵总是需要O(V^2)
的空间,不论图中有多少边。
优点:
简单、直观。
检查两个顶点之间是否存在边的操作非常快(O(1)
时间复杂度)。
更适合表示密集图(边的数量接近V^2
)。
有一些比较好用的性质,比如n次幂矩阵https://blog.csdn.net/bairui6666/article/details/134595589
缺点:
对于稀疏图(边相对较少),空间效率低。
添加或删除边的操作需要O(1)
时间,但初始化很慢(需要初始化V^2
个元素)。
遍历一个顶点的所有邻接点需要O(V)
时间,即使该顶点的度(邻接点数量)很小。
//在给出各条边的关系的情况下初始化一个邻接矩阵
graph = [[0, 1], [0, 2], [1, 2], [1, 2]]
//邻接矩阵的初始化
vector>adjMatrix(n,vector(n,0));
for(const auto&edge:graph){
adjMatrix[edge[0]][edge[1]]=1;//有向图中表示两个顶点之间有通路
//adjMatrix[edge[1]][edge[0]]=1;无向图中两个顶点之间有通路
}
定义: 邻接表是一个数组的列表,数组中的每个元素是一个列表,表示与该顶点相邻的所有顶点。
空间复杂度: 对于有V
个顶点和E
条边的图,邻接表需要O(V + E)
的空间。
优点:
缺点:
O(V)
)。//给出边的关系
graph = [[0, 1], [0, 2], [1, 2], [1, 2]]
//邻接表的初始化
vector>adjList(n);
for (const auto& edge : graph) {
adjList[edge[0]].push_back(edge[1]);
}
void DFSUtil(int v, vector& visited, const vector>& adj) {
visited[v] = true;
// 访问当前节点v
for (int u : adj[v]) {
if (!visited[u]) {
DFSUtil(u, visited, adj);
}
}
}
void DFS(int V, const vector>& adj, int start) {
vector visited(V, false);
DFSUtil(start, visited, adj);
}
void BFS(int V, const vector>& adj, int start) {
vector visited(V, false);
queue queue;
visited[start] = true;
queue.push(start);
while (!queue.empty()) {
int v = queue.front();
queue.pop();
// 访问节点v
for (int u : adj[v]) {
if (!visited[u]) {
visited[u] = true;
queue.push(u);
}
}
}
}
一道很好的模板题
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
void dfs(vector&vis,vector>&graph,int curr){
vis[curr]=true;
for(int now:graph[curr]){
if(!vis[now]){
dfs(vis,graph,now);
}
}
}
bool bfs(vector>&graph,int target,int start){
queuetovis;
vectorvis(graph.size(),false);
vis[start]=true;
tovis.push(start);
while(!tovis.empty()){
int to=tovis.front();
tovis.pop();
vis[to]=true;
for(int next:graph[to]){
if(!vis[next]){
tovis.push(next);
}
}
}
return vis[target];
}
bool findWhetherExistsPath(int n, vector>& graph, int start, int target) {
vectorvis(n,false);
//邻接表的初始化
vector>adjList(n);
for (const auto& edge : graph) {
adjList[edge[0]].push_back(edge[1]);
}
//邻接矩阵的初始化
vector>adjMatrix(n,vector(n,0));
for(const auto&edge:graph){
adjMatrix[edge[0]][edge[1]]=1;//有向图中表示两个顶点之间有通路
//adjMatrix[edge[1]][edge[0]]=1;无向图中两个顶点之间有通路
}
//dfs(vis,adjList,0); return vis[target];
return bfs(adjList,target,start);
}
};