《算法》第四章部分程序 part 5
▶ 书中第四章部分程序,加上自己补充的代码,图的深度优先遍历
● 无向图的广度优先遍历,有向 / 无向图代码仅若干方法名不同
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Graph;
import edu.princeton.cs.algs4.Stack;
import edu.princeton.cs.algs4.Queue; public class class01
{
private static final int INFINITY = Integer.MAX_VALUE;
private boolean[] marked; // 顶点是否已被遍历
private int[] edgeTo; // 每个顶点在 s - v 路径中的父顶点
private int[] distTo; // 每个顶点在 s - v 路径中的路径长 public class01(Graph G, int s)
{
marked = new boolean[G.V()];
distTo = new int[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = INFINITY;
nonRecursiveBFS(G, s);
//assert check(G, s);
} private void nonRecursiveBFS(Graph G, int s)
{
Queue<Integer> q = new Queue<Integer>();
distTo[s] = 0;
marked[s] = true;
for (q.enqueue(s); !q.isEmpty();)
{
int v = q.dequeue();
for (int w : G.adj(v))
{
if (!marked[w])
{
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
} private void nonRecursiveBFS(Graph G, Iterable<Integer> sources) // 以迭代器元素为起点列表进行遍历
{
Queue<Integer> q = new Queue<Integer>();
for (int s : sources)
{
marked[s] = true;
distTo[s] = 0;
q.enqueue(s);
}
for (;!q.isEmpty();)
{
int v = q.dequeue();
for (int w : G.adj(v))
{
if (!marked[w])
{
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
} public boolean marked(int v)
{
return marked[v];
} public int distTo(int v)
{
return distTo[v];
} public Iterable<Integer> pathTo(int v)
{
if (!marked(v))
return null;
Stack<Integer> path = new Stack<Integer>();
int x;
for (x = v; distTo[x] != 0; x = edgeTo[x])
path.push(x);
path.push(x);
return path;
} private boolean check(Graph G, int s)
{
if (distTo[s] != 0)
{
StdOut.println("\n<check> error distance of s.\n");
return false;
}
for (int v = 0; v < G.V(); v++)
{
for (int w : G.adj(v))
{
if (marked(v) != marked(w)) // 检查边正确性
{
StdOut.println("edge " + v + "-" + w);
StdOut.println("marked(" + v + ") = " + marked(v));
StdOut.println("marked(" + w + ") = " + marked(w));
return false;
}
if (marked(v) && (distTo[w] > distTo[v] + 1)) // 检查顶点 v 相连的顶点的距离正确性
{
StdOut.println("edge " + v + "-" + w);
StdOut.println("distTo[" + v + "] = " + distTo[v]);
StdOut.println("distTo[" + w + "] = " + distTo[w]);
return false;
}
}
}
for (int w = 0; w < G.V(); w++)
{
if (!marked(w) || w == s)
continue;
int v = edgeTo[w];
if (distTo[w] != distTo[v] + 1) // 逐边检查距离正确性
{
StdOut.println("shortest path edge " + v + "-" + w);
StdOut.println("distTo[" + v + "] = " + distTo[v]);
StdOut.println("distTo[" + w + "] = " + distTo[w]);
return false;
}
}
return true;
} public static void main(String[] args)
{
In in = new In(args[0]);
int s = Integer.parseInt(args[1]);
Graph G = new Graph(in);
class01 search = new class01(G, s);
for (int v = 0; v < G.V(); v++)
{
if (search.marked(v))
{
StdOut.printf("%d to %d (%d): ", s, v, search.distTo(v));
for (int x : search.pathTo(v))
{
if (x == s)
StdOut.print(x);
else
StdOut.print("-" + x);
}
StdOut.println();
}
else
StdOut.printf("%d to %d (-): not connected\n", s, v);
}
}
}
● 有向图广度优先遍历
package package01; import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Digraph;
import edu.princeton.cs.algs4.Stack;
import edu.princeton.cs.algs4.Queue; public class class01
{
private static final int INFINITY = Integer.MAX_VALUE;
private boolean[] marked;
private int[] edgeTo;
private int[] distTo; public class01(Digraph G, int s)
{
marked = new boolean[G.V()];
distTo = new int[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = INFINITY;
nonRecursiveBFS(G, s);
} private void nonRecursiveBFS(Digraph G, int s)
{
Queue<Integer> q = new Queue<Integer>();
distTo[s] = 0;
marked[s] = true;
for (q.enqueue(s); !q.isEmpty();)
{
int v = q.dequeue();
for (int w : G.adj(v))
{
if (!marked[w])
{
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
} private void nonRecursiveBFS(Digraph G, Iterable<Integer> sources)
{
Queue<Integer> q = new Queue<Integer>();
for (int s : sources)
{
marked[s] = true;
distTo[s] = 0;
q.enqueue(s);
}
for (;!q.isEmpty();)
{
int v = q.dequeue();
for (int w : G.adj(v))
{
if (!marked[w])
{
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
} public boolean marked(int v)
{
return marked[v];
} public int distTo(int v)
{
return distTo[v];
} public Iterable<Integer> pathTo(int v)
{
if (!marked(v))
return null;
Stack<Integer> path = new Stack<Integer>();
int x;
for (x = v; distTo[x] != 0; x = edgeTo[x])
path.push(x);
path.push(x);
return path;
} public static void main(String[] args)
{
In in = new In(args[0]);
int s = Integer.parseInt(args[1]);
Digraph G = new Digraph(in);
class01 search = new class01(G, s);
for (int v = 0; v < G.V(); v++)
{
if (search.marked(v))
{
StdOut.printf("%d to %d (%d): ", s, v, search.distTo(v));
for (int x : search.pathTo(v))
{
if (x == s)
StdOut.print(x);
else
StdOut.print("->" + x);
}
StdOut.println();
}
else
StdOut.printf("%d to %d (-): not connected\n", s, v);
}
}
}
《算法》第四章部分程序 part 5的更多相关文章
- 《算法》第四章部分程序 part 19
▶ 书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall 算法可能含负环的有边权有向图任意两点之间的最短路径 ● 有边权有向图的邻接矩阵 package p ...
- 《算法》第四章部分程序 part 18
▶ 书中第四章部分程序,包括在加上自己补充的代码,在有权有向图中寻找环,Bellman - Ford 算法求最短路径,套汇算法 ● 在有权有向图中寻找环 package package01; impo ...
- 《算法》第四章部分程序 part 16
▶ 书中第四章部分程序,包括在加上自己补充的代码,Dijkstra 算法求有向 / 无向图最短路径,以及所有顶点对之间的最短路径 ● Dijkstra 算法求有向图最短路径 package packa ...
- 《算法》第四章部分程序 part 15
▶ 书中第四章部分程序,包括在加上自己补充的代码,Kruskal 算法和 Boruvka 算法求最小生成树 ● Kruskal 算法求最小生成树 package package01; import e ...
- 《算法》第四章部分程序 part 14
▶ 书中第四章部分程序,包括在加上自己补充的代码,两种 Prim 算法求最小生成树 ● 简单 Prim 算法求最小生成树 package package01; import edu.princeton ...
- 《算法》第四章部分程序 part 10
▶ 书中第四章部分程序,包括在加上自己补充的代码,包括无向图连通分量,Kosaraju - Sharir 算法.Tarjan 算法.Gabow 算法计算有向图的强连通分量 ● 无向图连通分量 pack ...
- 《算法》第四章部分程序 part 9
▶ 书中第四章部分程序,包括在加上自己补充的代码,两种拓扑排序的方法 ● 拓扑排序 1 package package01; import edu.princeton.cs.algs4.Digraph ...
- 《算法》第四章部分程序 part 17
▶ 书中第四章部分程序,包括在加上自己补充的代码,无环图最短 / 最长路径通用程序,关键路径方法(critical path method)解决任务调度问题 ● 无环图最短 / 最长路径通用程序 pa ...
- 《算法》第四章部分程序 part 13
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序.后序和逆后续遍历,以及传递闭包 ● 图的前序.后序和逆后续遍历 package package01; import edu.princeto ...
- 《算法》第四章部分程序 part 12
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的几种补充数据结构,包括无向 / 有向符号图,有权边结构,有边权有向图 ● 无向符号图 package package01; import edu. ...
随机推荐
- 根据数据库结构生成TreeView
procedure TUIOperate.FillTree(treeview: TTreeView); var findq: TADOQuery; node: TTreeNode; //这个方法是根据 ...
- Oracle Split字符串
为了让 PL/SQL 函数返回数据的多个行,必须通过返回一个 REF CURSOR 或一个数据集合来完成.REF CURSOR 的这种情况局限于可以从查询中选择的数据,而整个集合在可以返回前,必须进行 ...
- Linux 如何测试 IO 性能(磁盘读写速度)
这几天做MySQL性能测试,偌大一个公司,找几台性能测试机器都很纠结,终于协调到两台,IO的性能如何还不知道.数据库属于IO密集型的应用,所以还是先评估下Server的IO性能,看看是否能和线上的机器 ...
- 1.linux6 x86-64 RPM包安装mysql5.7.20
注意版本和此次更新时间 2017-12-03 版本:mysql-5.7.20-1.el6.x86_64 环境:linux6.x 官方下载地址: wget https://dev.mysql.co ...
- onsubmit ajax return false 无效
var flat=false; return flat; async:false, 是重点. 执行ajax时return false的function 与onsubmit()不是同一个函数,所以无 ...
- Restful API设计规范及实战【说的比较清楚了】
Restful API设计规范及实战 Restful API的概念在此就不费口舌了,博友们网上查哈定义文章很多,直入正题吧: 首先抛出一个问题:判断id为 用户下,名称为 使命召唤14(COD14 ...
- onunload事件火狐不支持,在IE浏览器中,只有刷新时该事件才发生
onunload事件火狐不支持,在IE浏览器中,只有刷新时该事件才发生
- 在Linux里安装Samba(文件共享)方便在Windows下面操作
第一步:安装包 在CentOS是 yum install samba 在Ubuntu是 apt install samba 第二步:添加用户 adduser 用户名 smbpasswd -a 用户名 ...
- centos7.0KVM虚拟化
需要在图形化界面完成实验 查看CPU信息 # cat /proc/cpuinfo centos7默认安装的虚拟化包 # yum list open*tools 如果没安装就安装 #yum instal ...
- AMQP & JMS对比(转载)
AMQP & JMS对比 原文地址:https://blog.csdn.net/hpttlook/article/details/23391967 初次接触消息队列时,在网上搜索,总是会提到如 ...