▶ 书中第四章部分程序,加上自己补充的代码,图的深度优先遍历

● 无向图的深度优先遍历,有向 / 无向图代码仅若干方法名不同,包括递归和非递归版本,去掉了顶点有效性的检查

 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的更多相关文章

  1. 《算法》第四章部分程序 part 19

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall 算法可能含负环的有边权有向图任意两点之间的最短路径 ● 有边权有向图的邻接矩阵 package p ...

  2. 《算法》第四章部分程序 part 18

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,在有权有向图中寻找环,Bellman - Ford 算法求最短路径,套汇算法 ● 在有权有向图中寻找环 package package01; impo ...

  3. 《算法》第四章部分程序 part 16

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,Dijkstra 算法求有向 / 无向图最短路径,以及所有顶点对之间的最短路径 ● Dijkstra 算法求有向图最短路径 package packa ...

  4. 《算法》第四章部分程序 part 15

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,Kruskal 算法和 Boruvka 算法求最小生成树 ● Kruskal 算法求最小生成树 package package01; import e ...

  5. 《算法》第四章部分程序 part 14

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,两种 Prim 算法求最小生成树 ● 简单 Prim 算法求最小生成树 package package01; import edu.princeton ...

  6. 《算法》第四章部分程序 part 10

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,包括无向图连通分量,Kosaraju - Sharir 算法.Tarjan 算法.Gabow 算法计算有向图的强连通分量 ● 无向图连通分量 pack ...

  7. 《算法》第四章部分程序 part 9

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,两种拓扑排序的方法 ● 拓扑排序 1 package package01; import edu.princeton.cs.algs4.Digraph ...

  8. 《算法》第四章部分程序 part 17

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,无环图最短 / 最长路径通用程序,关键路径方法(critical path method)解决任务调度问题 ● 无环图最短 / 最长路径通用程序 pa ...

  9. 《算法》第四章部分程序 part 13

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序.后序和逆后续遍历,以及传递闭包 ● 图的前序.后序和逆后续遍历 package package01; import edu.princeto ...

  10. 《算法》第四章部分程序 part 12

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,图的几种补充数据结构,包括无向 / 有向符号图,有权边结构,有边权有向图 ● 无向符号图 package package01; import edu. ...

随机推荐

  1. linux新手非常有用的20个命令

    引用:http://www.oschina.net/translate/useful-linux-commands-for-newbies 1. ls命令 ls命令是列出目录内容(List Direc ...

  2. PByte和PChar的关系

    作为指针是相同的, 解析的内容,稍微有点区别. var s:String;P:PChar;B:PByte;a:Integer;begin  s:='1234';  P:=PChar(s);//按chr ...

  3. PrintWriter中的write与println方法居然就是这些区别

    为什么循环中分别用write方法和println方法效果一样呢? import java.io.*; public class WriteLog { private BufferedReader bf ...

  4. linux开机出现一下错误Give root password for maintenance (or type Control-D to continue):

    由于错误的编辑/etc/fstab文件 而引起的不能正常进入系统.假如你将某一个分区或者磁盘最后一个参数设置为1或2时,系统默认会在开机过程中检查这个磁盘的扇区.假如系统检查不到这个磁盘,或者这个磁盘 ...

  5. STL基础--算法(不修改数据的算法)

    不修改数据的算法 count, min and max, compare, linear search, attribute // 算法中Lambda函数很常用: num = count_if(vec ...

  6. vagrant 本地添加box 支持带版本号

    众所周知,vagrant添加box的时候要从外网下载,那速度...(说多了都是泪),所以只好用下载工具下载到本地之后再添加. 一般处理方案 vagrant box add boxName ./down ...

  7. 【转载】这样去写你的HTML

    昨天在 twitter 上说,怎么忍心把页面写得这么难用?是的,这个世界还有一群人等着我们创建出来的东西,可以让他们的生活能过得更容易呢.比如那些需要读屏软件的用户.作为一个前端,我们又怎么会忍心呢. ...

  8. MySQL学习----各种字符的长度总结

    数字型 类型 大小 范围(有符号) 范围(无符号) 用途 TINYINT 1 字节 (-128,127) (0,255) 小整数值 SMALLINT 2 字节 (-32 768,32 767) (0, ...

  9. maven使用笔记--在父pom中声明过的jar可以被继承,使子项目不用写版本号由父pom控制

    将dependencies放到dependencyManagement中,如下: [html] view plaincopy <dependencyManagement> <depe ...

  10. 实现textview竖排文字效果

    文字效果