图算法

Prim 普里姆算法

思路: 该算法采用贪心思想,在图中任意选择一结点构建一颗生成树然后从所有与该生成树相邻的结点中取出最近的结点和边加入到生成树中.直到所有的结点都加入到该生成树中.

算法复杂度 ElogV
采用最小优先队列存放剩余的结点,每次从该最小队列中选出与生成树之间最小的结点加入生成树中,同时更新最小队列.

克鲁斯卡尔

克鲁斯卡尔算法每次从剩余的边中选择一个最小的边,如果当前边和已选取的边构成回路,则放弃该并选择下一个最小边。如果不构成回路则将该边以及连接的两个结点加入的生成树中.直到完成整棵生成树的构建.

时间复杂度, ElogE

迪杰斯特拉 Dijkstra

思路: 它应用了贪心算法模式,算法解决的是有向图中单个源点到其他顶点的最短路径问题.引进两个集合S和T。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而T则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离)。
初始时,S中只有起点v0;T中是除v0之外的顶点,并且T中顶点的路径是”起点s到该顶点的路径”。从T中选择一个到v0最短的顶点vi并加入到S中.如果T集合中的结点以vi作为中转站到达s的距离比原来的小则更新对应的值.依次迭代,直到将T中的所有结点加入S中.

算法复杂度 ElogV

弗洛伊德 Floyed

是采用动态规划的思想计算任意两个结点之间的最短路径.
1) 初始化距离矩阵,对于所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
2,对于每一对顶点 u 和 v,看看其他结点中否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。

时间复杂度O(V^3)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Floyed {
private final int INF = Integer.MAX_VALUE;
public void Floyd(int[][] matrix) {
int[][] path = new int[matrix.length][matrix[0].length];
int[][] dist = new int[matrix.length][matrix[0].length];
int size = matrix.length;
//初始化
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
path[i][j] = -1;
dist[i][j] = matrix[i][j];
}
}
for (int k = 0; k < size; k++) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = k;
}
}
}
}
}
}

图的遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class Graph {
int v; //结点数
int e; //边数
VNode[] nodes;//邻接表
class VNode{
int data;
ArcNode firstArc;
}
class ArcNode{
int adjvex;//该边锁指向的结点位置
ArcNode nextArc;
}
/**
* 对某个点进行深度优先搜索
* @param g
* @param v
*/
public void dfs(Graph g,int v){
if(g == null || g.nodes == null || g.nodes.length < v)
return;

boolean[] marked = new boolean[g.v];
dfs(g,v,marked);
}
private void dfs(Graph g, int v, boolean[] marked) {
marked[v] = true;
ArcNode adj = g.nodes[v].firstArc;
while(adj != null){
if(!marked[adj.adjvex])
dfs(g,adj.adjvex,marked);
adj = adj.nextArc;
}
}
/**
* 广度优先搜索
* @param g
* @param v
*/
public void bfs(Graph g,int v){
if(g == null || g.nodes == null || g.nodes.length < v)
return;
boolean[] marked = new boolean[g.v];
Queue<VNode> queue = new LinkedList<VNode>();
queue.offer(g.nodes[v]);
marked[v] = true;
while(!queue.isEmpty()){
ArcNode adj = queue.poll().firstArc;
while(adj != null){
if(!marked[adj.adjvex]){
queue.offer(g.nodes[adj.adjvex]);
}
adj = adj.nextArc;
}
}
}
}
0%