Graph、DFS、BFS
Graph.java
package Graph; import LinearLIst.bag.Bag;
import edu.princeton.cs.algs4.In; public class Graph { private final int V; //顶点数目
private int E; //边的数目
private Bag<Integer>[] adj; //邻接表 /*创建一个包含V个顶点但是不包含边的图*/
public Graph(int V){
this.V=V;
this.E=0;
adj=(Bag<Integer>[]) new Bag[V]; //创建邻接表
for(int v=0;v<V;v++) //将所有链表初始化为空
adj[v]=new Bag<Integer>();
} /*从标准输入流读入一幅图*/
public Graph(In in){
this(in.readInt()); //读取V并将图初始化
int E=in.readInt(); //读取E
for (int i=0;i<E;i++){
int v=in.readInt(); //读取一个顶点
int w=in.readInt(); //读取另一个顶点
addEdge(v,w); //添加一条连接他们的边
}
} /**
* 返回图中顶点(结点)数目
*/
public int V(){
return V;
} /**
*返回图中边的数目
*/
public int E(){
return E;
} /*向图中增加一条边v-w */
public void addEdge(int v,int w){
adj[v].add(w); //将W添加到V的链表中
adj[w].add(v); //将V添加到W的链表中
E++;
} /*和v相邻的所有顶点*/
/*返回的是该点的邻接表*/
public Iterable<Integer> adj(int v){
return adj[v];
} /*下面是最常用的图处理操作*/ /*计算v的度数*/
public static int degree(Graph G,int v){
int degree=0;
for (int w:G.adj(v))
degree++;
return degree;
} /*计算所有顶点的最大度数*/
public static int maxDegree(Graph G){
int max=0;
for (int v=0;v<G.V();v++){
if (degree(G,v)>max)
max=degree(G,v);
}
return max;
} /*计算所有顶点的平均度数*/
public static double avgDegree(Graph G){
return 2*G.E()/G.V();
} /*计算子环的个数*/
public static int numberOfSelfLoops(Graph G){
int count=0;
for (int v=0;v<G.V();v++)
for (int w:G.adj(v))
if (v==w)
count++;
return count/2;
} /*图的邻接表的字符串表示*/
public String toString(){
String s=V+" vertices,"+E+" edges\n"; for (int v=0;v<V;v++){
s+=v+": ";
for (int w:this.adj(v))
s+=w+" ";
s+="\n";
}
return s;
} }
DepthFirstSearch.java
package Graph;
public class DepthFirstSearch {
/*marked数组的索引代表一个顶点,元素值代表该点与起点s是否联通*/
private boolean[] marked;
/*与s联通的点的总数*/
/*需要注意的是,这里不是指与s相邻的点的数量*/
/*s与自己是联通的*/
/*即s所在的联通子图中顶点的数量*/
private int count;
/**
*
* @param G 一个图
* @param s s代表图中的起点
*/
public DepthFirstSearch(Graph G,int s){
marked=new boolean[G.V()];
dfs(G,s);
}
private void dfs(Graph G,int v){
marked[v]=true;
count++;
for(int w:G.adj(v)){
if (!marked[w])
dfs(G,w);
}
}
/**
*
* @param w:输入一个顶点
* @return 该顶点是否与起点s联通
*/
public boolean marked(int w){
return marked[w];
}
/**
*
* @return 与s联通的点的总数(所在联通子图的节点数)
*/
public int count(){
return count;
}
}
DepthFirstPaths.java
package Graph; import LinearLIst.stack.Stack;
import edu.princeton.cs.algs4.In; public class DepthFirstPaths {
private boolean[] marked;
private int[] edgeTo;
private final int s; public DepthFirstPaths(Graph G,int s){
marked=new boolean[G.V()];
edgeTo=new int[G.V()];
this.s=s;
dfs(G,s);
} private void dfs(Graph G,int v) {
marked[v] = true;
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
}
}
} public boolean hasPathTo(int v) {
return marked[v];
} 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;
}
}
BreadthFirstSearch.java
package Graph;
import LinearLIst.queue.Queue;
public class BreadthFirstSearch {
/*从起点s到达某个顶点的最短路径是否已知*/
private boolean[] marked;
/*到达该顶点的已知路径上的最后一个顶点*/
/*“最短路径的最后一条边”*/
private int[] edgeTo;
/*起点*/
private final int s;
public BreadthFirstSearch(Graph G,int s){
/*V()返回的是图中顶点的数目*/
marked=new boolean[G.V()];
edgeTo=new int[G.V()];
this.s=s;
bfs(G,s);
}
private void bfs(Graph G,int s){
Queue<Integer> queue=new Queue<Integer>();
marked[s]=true; //标记起点
queue.enqueue(s); //将其加入队列
while(!queue.isEmpty()){
int v=queue.dequeue(); //从队列中删去下一顶点
for (int w:G.adj(v)){
edgeTo[w]=v; //保存最短路径的最后一条边
marked[w]=true; //标记它。因为最短路径已知
queue.enqueue(w); //将它加入到队列中
}
}
}
/*判断一个顶点与s是否联通*/
public boolean hasPathTo(int v){
return marked[v];
}
/*得到一条从s到v的路径*/
/*确保没有从其它s到v的路径所含的边比这条路径更少*/
/*
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;
}
*/
}
Graph、DFS、BFS的更多相关文章
- B. Kay and Snowflake 解析(思維、DFS、DP、重心)
Codeforce 685 B. Kay and Snowflake 解析(思維.DFS.DP.重心) 今天我們來看看CF685B 題目連結 題目 給你一棵樹,要求你求出每棵子樹的重心. 前言 完全不 ...
- D. New Year Santa Network 解析(思維、DFS、組合、樹狀DP)
Codeforce 500 D. New Year Santa Network 解析(思維.DFS.組合.樹狀DP) 今天我們來看看CF500D 題目連結 題目 給你一棵有邊權的樹,求現在隨機取\(3 ...
- B. Two Fairs 解析(思維、DFS、組合)
Codeforce 1276 B. Two Fairs 解析(思維.DFS.組合) 今天我們來看看CF1276B 題目連結 題目 給一個連通圖,並給兩個點(\(a,b\)),求有多少點對使得:任一路徑 ...
- D. Maximum Distributed Tree 解析(思維、DFS、組合、貪心、DP)
Codeforce 1401 D. Maximum Distributed Tree 解析(思維.DFS.組合.貪心.DP) 今天我們來看看CF1401D 題目連結 題目 直接看原題比較清楚,略. 前 ...
- DFT、DTFT、DFS、FFT之间的关系
DFT.DTFT.DFS.FFT.FT.FS之间的关系 FT和FS是研究连续信号的,在数字信号处理中不涉及. 主要是前四种的关系: DFT(Discrete Fourier Transform):离散 ...
- 图、dfs、bfs
graphdfsbfs 1.clone graph2.copy list with random pointer3.topological sorting4.permutations5.subsets ...
- 搜索(BFS、DFS、回溯)
这类题是最简单的了都是一个套路,不像动态规划一类题一个套路,没做过就是不会也极难想出来. 一.BFS 解决的问题:用来初始点解决到指定点的最短路径问题,因为图的每一层上的点到初始点的距离相同.(注意是 ...
- BFS、DFS、先序、中序、后序遍历的非递归算法(java)
一 广度优先遍历(BFS) //广度优先遍历二叉树,借助队列,queue public static void bfs(TreeNode root){ Queue<TreeNode> qu ...
- 九度OJ 1091:棋盘游戏 (DP、BFS、DFS、剪枝)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1497 解决:406 题目描述: 有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代 ...
随机推荐
- Elasticsearch学习笔记-Delete By Query API
记录关于Elasticsearch的文档删除API的学习 首先官网上Document APIs介绍了 Delete API 和Delete By Query API. Delete API可以通过指定 ...
- 4 LinkedList
1 LinkedList public class LinkedList<E> extends AbstractSequentialList<E> implements Lis ...
- FFmpeg之Linux下编译与调试
注:下面的一切都是在 root 模式下进行的,可以不再 root 模式下进行 1. 安装linux的基础环境 基础环境就是编译代码的基础库,Ubuntu联网安装软件很简单,一个语句即可搞定,这里列出语 ...
- Echarts4+EchartsGL 3D迁徙图(附源码)
最近遇到些Echarts迁徙图问题,在实现二维地图的迁徙图后开始开发3D迁徙图,在网上一查,发现3D版本迁徙图资料较少,自己研究并借鉴一些资料后写了一个小demo,希望能帮大家少走些弯路,共同学习. ...
- box-sizing Bootstrap
https://getbootstrap.com/docs/4.0/getting-started/introduction/#box-sizing Box-sizing For more strai ...
- Devops(一):CentOS7 安装Maven3.6.1详解
https://yq.aliyun.com/topic/78?spm=5176.8290451.656547.7.rMYhAF https://yq.aliyun.com/activity/155?u ...
- [java]将秒数转化为“天时分秒”的格式(转贴+修改)
public class Time { // format seconds to day hour minute seconds style // Exmplae 5000s will be form ...
- Python3+RobotFramewok 用户自定义库的开发(四)
在介绍这个之前,可以先看下python的目录Python\Lib\site-packages下面的文件夹,你会发现这个目录下面有DatabaseLibrary.RequestsLibrary.Sele ...
- cron表达式的用法
cron表达式通过特定的规则指定时间,用于定时任务,本文简单记录它的部分语法和实例,并不完全,能覆盖日常大部分需求. 1. 整体结构 cron表达式是一个字符串,分为6或7个域,每两个域之间用空格分隔 ...
- js 中 new call apply bind JSON.stringify 的原理以及模拟实现
1.new的原理和实现 它创建了一个全新的对象. 它会被执行 [[Prototype]](也就是 __proto__)链接. 它使 this指向新创建的对象. 通过 new创建的每个对象将最终被 [[ ...