G[i][j] = 1: <vi, vj>是G的边
? =0: 无边
0 | 1 | ... | n | |
---|---|---|---|---|
0 | 0 | 1 | 0 | |
1 | 1 | 0 | ||
... | 0 | 0 | ||
n | ... | ... | ... | 0 |
无向图用全阵浪费一半空间
方案:用链表(单行)表示元素下表:(i*(i+1)/2+j)
ps:整个表看起来:对角线为0,对称
0 | ||||
---|---|---|---|---|
... | 0 | |||
... | ... | 0 | ||
... | ... | ... | 0 | |
... | ... | ... | ... | 0 |
对于网络:值表示权重
网络:有权重的图
ps:用这种方法表示的图够稀疏才划算,且:图的表示并非只有这两种,要根据实际情况来设计
G[0]: 指针数组
G[0] --> |下标|指针域| --> |下标|指针域| --> ...
G[1] --> |下标|指针域| --> |下标|指针域| --> ...
...
G[n-1] --> |下标|指针域| --> |下标|指针域| --> ...
ps: 对于带权的网络,还要另加一个域表示权重
特点:
void DFS(Vertex V){
visited[V] = true; //点亮第一盏灯
for(v的每一个邻接点W){ //观察与v相连的灯
if(!visited[W]) //若未被点
DFS(W); //点亮,进入堆栈
}
}
对于N个顶点,E条边的图,时间复杂度:
自然语言描述:往下走,遇到路口挑第一个走,走到不通就往回退,退到起点遍历完成
类似树的BFS,树是特殊的图,借助队列来实现
void BFS(Vertex V){
visited[V] = true;//点灯
Enqueue(V, Q);//将与V相连的点入队
while(!IsEmpty(Q)){//队列不空
V = Dequeue(Q);//出队
for(V的每个邻接点W){
visited[w] = true;//电灯
Enqueue(W,Q);//入队
}
}
}
对于N个顶点,E条边的图,时间复杂度:
为何需要两种遍历
每种遍历适用于不同情况,故两种皆有用
图不连通怎么办
//每一个DFS都是在把图的一个连通分量遍历(不连通的部分为一个连通分量)
void ListComponent(Graph G){
for(each V in G)//每个连通分量处理一遍
if(!visited[V])
DFS(V);
}
源点:起点
最短路径
按递增(非递减)的顺序找出到各个顶点的最短路
原文:https://www.cnblogs.com/blogs-hjq/p/14669160.html