《算法》第四章部分程序 part 4
▶ 书中第四章部分程序,加上自己补充的代码,图的深度优先遍历
● 无向图的深度优先遍历,有向 / 无向图代码仅若干方法名不同,包括递归和非递归版本,去掉了顶点有效性的检查
package package01; import java.util.Iterator; // nonRecursiveDFS 需要
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Graph;
import edu.princeton.cs.algs4.Stack; // recursiveDFS 不用 public class class01
{
private final int s; // 根顶点,depthFirstPath 需要
private boolean[] marked; // 顶点是否已被遍历
private int count; // 已遍历的顶点数(含后退),即从 s 可达的顶点数,depthFirstPath 不用
private int[] edgeTo; // 每个顶点在 s - v 路径中的父顶点,depthFirstPath 需要 public class01(Graph G, int inputS) // 初始化,开始DFS
{
s = inputS;
marked = new boolean[G.V()];
edgeTo = new int[G.V()];
recursiveDFS(G, s);
} private void recursiveDFS(Graph G, int v)
{
count++;
marked[v] = true;
for (int w : G.adj(v))
{
if (!marked[w])
{
edgeTo[w] = v; // depthFirstPath 需要
recursiveDFS(G, w);
}
}
} public void nonRecursiveDFS(Graph G, int s) // 非递归版本
{
marked = new boolean[G.V()];
Iterator<Integer>[] adj = (Iterator<Integer>[]) new Iterator[G.V()];// 记录每个顶点处已经遍历到了哪一个链表节点
for (int v = 0; v < G.V(); v++)
adj[v] = G.adj(v).iterator();
Stack<Integer> stack = new Stack<Integer>();
marked[s] = true;
for (stack.push(s); !stack.isEmpty();)
{
int v = stack.peek();
if (adj[v].hasNext())
{
int w = adj[v].next();
if (!marked[w])
{
marked[w] = true;
stack.push(w);
}
}
else
stack.pop();
}
} public boolean marked(int v)
{
return marked[v];
} public int count()
{
return count;
} public Iterable<Integer> pathTo(int v)
{
if (!hasPathTo(v))
return null;
Stack<Integer> path = new Stack<Integer>();
for (int x = v; x != s; x = edgeTo[x]) // 从终点向起点压栈,以后吐栈的时候就是从起点到终点
path.push(x);
path.push(s);
return path;
} 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: ", s, 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);
}
if (search.count() != G.V())
StdOut.println("\nNot connected.\n");
else
StdOut.println("\nConnected.\n");
}
}
● 有向图的深度优先遍历
package package01; import java.util.Iterator;
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Digraph;
import edu.princeton.cs.algs4.Stack; public class class01
{
private final int s;
private boolean[] marked;
private int count;
private int[] edgeTo; public class01(Digraph G, int inputS)
{
s = inputS;
marked = new boolean[G.V()];
edgeTo = new int[G.V()];
recursiveDirectedDFS(G, s);
} private void recursiveDirectedDFS(Digraph G, int v)
{
count++;
marked[v] = true;
for (int w : G.adj(v))
{
if (!marked[w])
{
edgeTo[w] = v;
recursiveDirectedDFS(G, w);
}
}
} public void nonRecursiveDirectedDFS(Digraph G, int s)
{
marked = new boolean[G.V()];
Iterator<Integer>[] adj = (Iterator<Integer>[]) new Iterator[G.V()];
for (int v = 0; v < G.V(); v++)
adj[v] = G.adj(v).iterator();
Stack<Integer> stack = new Stack<Integer>();
marked[s] = true;
for (stack.push(s); !stack.isEmpty();)
{
int v = stack.peek();
if (adj[v].hasNext())
{
int w = adj[v].next();
if (!marked[w])
{
marked[w] = true;
stack.push(w);
}
}
else
stack.pop();
}
} public boolean marked(int v)
{
return marked[v];
} public int count()
{
return count;
} public Iterable<Integer> pathTo(int v)
{
if (!hasPathTo(v))
return null;
Stack<Integer> path = new Stack<Integer>();
for (int x = v; x != s; x = edgeTo[x])
path.push(x);
path.push(s);
return path;
} 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: ", s, 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);
}
if (search.count() != G.V())
StdOut.println("\nNot connected.\n");
else
StdOut.println("\nConnected.\n");
}
}
《算法》第四章部分程序 part 4的更多相关文章
- 《算法》第四章部分程序 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. ...
随机推荐
- QT建立简单的计时器程序
1.创建一个窗口项目 2.拖一个lcd控件命名lcdNumber,两个pushbutton,分别命名pbStart与pbEnd 3.mainWindow.h添加以下代码 private slots: ...
- 机器学习笔记——t分布知识点总结
(原创文章,转载请注明地址:http://www.cnblogs.com/wangkundentisy/p/6539058.html ) 1.t分布式统计分布的一种,同卡方分布(χ2分布).F分布并称 ...
- 使用R语言-计算均值,方差等
R语言对于数值计算很方便,最近用到了计算方差,标准差的功能,特记录. 数据准备 height <- c(6.00, 5.92, 5.58, 5.92) 1 计算均值 mean(height) [ ...
- bzoj5008: 方师傅的房子
Description 方师傅来到了一个二维平面.他站在原点上,觉得这里风景不错,就建了一个房子.这个房子是n个点的凸多边形 ,原点一定严格在凸多边形内部.有m个人也到了这个二维平面.现在你得到了m个 ...
- python面向对象 : 属性, 类方法, 静态方法
一. 属性 属性: 将方法伪装成一个属性,代码上没有什么提升,只是更合理. property应用 : 类似于bmi这种,area,周长.... 需要用到计算的. # 求BMI体质数:BMI = 体 ...
- UI相关教程:HUD、UMG和Widget
转自:http://aigo.iteye.com/blog/2258612 蓝图脚本来处理 ================================================== 用UM ...
- 删除win7任务栏通知区域图标的方法
大家都知道程序运行后会在任务栏的通知区域显示表明正在运行,但是有很多失效的图标也会在此显示,那么怎么样删除那些没用的图标呢? 1.在开始运行里输入:regedit进入注册表编辑器 2.进入注册表编辑器 ...
- for循环.html
<script> for (var i = 1; i < 5 ; i++) { alert(i); } 公式需要记住,并多加练习,加深记忆,注意编写格式 for (var i = 1 ...
- 【Unix网络编程】chapter6IO复用
chapter6 6.1 概述 I/O复用典型使用在下列网络应用场合. (1):当客户处理多个描述符时,必须使用IO复用 (2):一个客户同时处理多个套接字是可能的,不过不叫少见. (3):如果一个 ...
- solr如何让全词匹配结果在最前面
在全文搜索中默认排序是按照匹配度权值score排序的,权值越大位置越靠前,那为什么有很多时候全词匹配反而不在最前面那,其实很简单因为全词匹配权值也就是100,但是还有很多权值大于100的排在了前面. ...