Graph(图)
在面试的过程中,一般不会考到图相关的问题,因为图相关的问题难,而且描述起来很麻烦.
但是也会问道一下常见的问题,比如,最短路径,最小支撑树,拓扑排序都被问到过.
- 图常用的表示方法有两种: 分别是邻接矩阵和邻接表.
邻接矩阵是不错的一种图存储结构,对于边数相对顶点较少的图,这种结构存在对存储空间的极大浪费.
因此,找到一种数组与链表相结合的存储方法称为邻接表.
- 邻接矩阵表示的无向图
- 邻接表表示的无向图
1. 最短路径
- Dijkstra
- 维护一个最短路径的的集合(sptSet)和最短距离数组, 直到遍历所有的点, 初始化起始点的距离是0, 集合为空.
- 初始化起始点s到所有的点的距离是INF, 注意s到s的距离是0.
- while sptSet 不包含所有的顶点:
- 选择当前能到达点的最小距离的点u,加入 sptSet
- 使用u作为中间顶点,更新所有点的距离,选择最小距离的替换
- dist[u]+graph[u][v] < dist[v]
int minDistance(vector<int> dist, set<int> sptSet) {
int min_d = INT_MAX, u;
for(int i = 0, i < dist.size(); i ++) {
if(sptSet.find(i) == sptSet.end() && dist[v] < min_d) {
min_d = dist[i], u = i;
}
}
return u;
}
// 使用vector 表示的邻接矩阵, return 起始点到所有点的最小距离
// 没有边的用0填充
vector<int> dijstra(vector<vector<int>> graph, set<int> &sptSet,int src) {
int V = graph.size();
vector<int> dist(V, 0);
for(int i = 0;i < V; i ++) {
if(i != src) dist[i] = INT_MAX;
}
while(sptSet.size() < V-1) {
// pick mininum distance u
int u = minDistance(dist, sptSet);
sptSet.insert(u);
// 使用u更新距离
for(int v = 0; v < V; v ++) {
if(sptSet.find(v)==sptSet.end() && graph[u][v]
&& dist[u] != INT_MAX
&& dist[u]+graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}
return dist;
}
- Floyd Warshall
Floy