剑指Offer--图的操作
剑指Offer–图的操作
前言
企业笔试过程中会涉及到数据结构的方方面面,现将有关图的深度优先搜索与广度优先搜索进行整理归纳,方便日后查阅。
在已做过的笔试题目中,可用DFS解决的题目有:
三道题目都是DFS的经典应用,主要采用递归+回溯的方式。
下面主要讲解一下DFS与BFS的具体实现。
深度优先搜索(DFS) && 广度优先搜索(BFS)
package cn.edu.ujn.graph;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* @description 邻接矩阵模型类
* @author SHQ
* @time 2016.09.12
*/
public class DFS_BFS {
private ArrayList<Object> vertexList;// 存储点的链表
private int[][] edges; // 邻接矩阵,用来存储边
private int numOfEdges; // 边的数目
boolean[] isVisited; // 遍历标志位
public DFS_BFS(int n) {
//初始化矩阵,二维数组,和边的数目
edges = new int[n][n];
vertexList = new ArrayList<Object>(n);
numOfEdges = 0;
// 将所有节点访问标志位均置为未访问
isVisited = new boolean[n];
for(int i = 0; i < n; i++){
isVisited[i] = false;
}
}
// 得到结点的个数
public int getNumOfVertex() {
return vertexList.size();
}
// 得到边的数目
public int getNumOfEdges() {
return numOfEdges;
}
// 返回结点i的数据
public Object getValueByIndex(int i) {
return vertexList.get(i);
}
// 返回v1,v2的权值
public int getWeight(int v1,int v2) {
return edges[v1][v2];
}
//插入结点
public void insertVertex(Object vertex) {
vertexList.add(vertexList.size(),vertex);
}
//插入结点
public void insertEdge(int v1,int v2,int weight) {
edges[v1][v2]=weight;
numOfEdges++;
}
//删除结点
public void deleteEdge(int v1,int v2) {
edges[v1][v2] = 0;
numOfEdges--;
}
// 得到第一个邻接结点的下标
public int getFirstNeighbor(int index) {
for(int j = 0; j < vertexList.size(); j++) {
if (edges[index][j] > 0) {
return j;
}
}
return -1;
}
// 根据前一个邻接结点的下标来取得下一个邻接结点
public int getNextNeighbor(int v1, int v2) {
for (int j = v2+1; j < vertexList.size(); j++) {
if (edges[v1][j]>0) {
return j;
}
}
return -1;
}
// 私有函数,深度优先遍历
private void depthFirstSearch(boolean[] isVisited,int i) {
// 首先访问该结点,在控制台打印出来
System.out.print(getValueByIndex(i) + " ");
// 置该结点为已访问
isVisited[i] = true;
int w = getFirstNeighbor(i);
while (w != -1) {
if (!isVisited[w]) {
depthFirstSearch(isVisited,w);
}
w = getNextNeighbor(i, w);
}
}
// 对外公开函数,深度优先遍历,与其同名私有函数属于方法重载
public void depthFirstSearch() {
for(int i = 0; i < getNumOfVertex(); i++) {
//因为对于非连通图来说,并不是通过一个结点就一定可以遍历所有结点的。
if (!isVisited[i]) {
depthFirstSearch(isVisited,i);
}
}
}
/**
* 私有函数,广度优先遍历
* 遍历步骤:
* 1.访问初始结点v并标记结点v为已访问。
* 2.结点v入队列
* 3.当队列非空时,继续执行,否则算法结束。
* 4.出队列,取得队头结点u。
* 5.查找结点u的第一个邻接结点w。
* 6.若结点u的邻接结点w不存在,则转到步骤3;否则循环执行以下三个步骤:
* 1)若结点w尚未被访问,则访问结点w并标记为已访问。
* 2)结点w入队列
* 3)查找结点u的继w邻接结点后的下一个邻接结点w,转到步骤6。
* @param isVisited
* @param i
*/
private void broadFirstSearch(boolean[] isVisited, int i) {
int u, w;
// 借助辅助队列,记录访问顺序
LinkedList<Object> queue = new LinkedList<Object>();
// 访问结点i
System.out.print(getValueByIndex(i) + " ");
isVisited[i] = true;
// 结点入队列
queue.addLast(i);
while (!queue.isEmpty()) {
u = ((Integer)queue.removeFirst()).intValue();
w = getFirstNeighbor(u);
while(w != -1) {
if(!isVisited[w]) {
//访问该结点
System.out.print(getValueByIndex(w)+" ");
//标记已被访问
isVisited[w] = true;
//入队列
queue.addLast(w);
}
//寻找下一个邻接结点
w = getNextNeighbor(u, w);
}
}
}
//对外公开函数,广度优先遍历
public void broadFirstSearch() {
for(int i = 0; i < getNumOfVertex(); i++) {
if(!isVisited[i]) {
broadFirstSearch(isVisited, i);
}
}
}
}
Main.java
package cn.edu.ujn.graph;
public class Main {
public static void main(String args[]) {
int n = 8, e = 9; // 分别代表结点个数和边的数目
String labels[]={"1","2","3","4","5","6","7","8"}; // 结点的标识
DFS_BFS graph = new DFS_BFS(n);
for(String label : labels) {
graph.insertVertex(label); // 插入结点
}
//插入九条边
graph.insertEdge(0, 1, 1);
graph.insertEdge(0, 2, 1);
graph.insertEdge(1, 3, 1);
graph.insertEdge(1, 4, 1);
graph.insertEdge(3, 7, 1);
graph.insertEdge(4, 7, 1);
graph.insertEdge(2, 5, 1);
graph.insertEdge(2, 6, 1);
graph.insertEdge(5, 6, 1);
graph.insertEdge(1, 0, 1);
graph.insertEdge(2, 0, 1);
graph.insertEdge(3, 1, 1);
graph.insertEdge(4, 1, 1);
graph.insertEdge(7, 3, 1);
graph.insertEdge(7, 4, 1);
graph.insertEdge(6, 2, 1);
graph.insertEdge(5, 2, 1);
graph.insertEdge(6, 5, 1);
/* System.out.println("深度优先搜索序列为:");
graph.depthFirstSearch();
System.out.println();*/
System.out.println("广度优先搜索序列为:");
graph.broadFirstSearch();
}
}
剑指Offer--图的操作的更多相关文章
- 剑指Offer——Java实现栈和队列的互模拟操作
剑指Offer--Java实现栈和队列的互模拟操作 栈模拟队列 题目:JAVA实现用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 思路:其实就是把队列正常入 ...
- [剑指offer]09用两个栈实现队列插入和删除操作,C++实现
原创博文,转载请注明出处! # 本文为牛客网<剑指offer>刷题笔记 1.题目 # 用两个栈实现队列的插入和删除操作 2.思路 栈服从先入后出的原则处理数据,队列服从先入先出的原则处理数 ...
- 面试经典算法题集锦——《剑指 offer》小结
从今年 3 月份开始准备找实习,到现在校招结束,申请的工作均为机器学习/数据挖掘算法相关职位,也拿到了几个 sp offer.经历这半年的洗礼,自己的综合能力和素质都得到了一个质的提升. 实话说对于未 ...
- 剑指Offer——知识点储备--Linux基本命令+Makefile
剑指Offer--知识点储备–Linux基本命令 1.linux下查看进程占用cpu的情况(top): 格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 主要参 ...
- 剑指Offer——知识点储备-故障检测、性能调优与Java类加载机制
剑指Offer--知识点储备-故障检测.性能调优与Java类加载机制 故障检测.性能调优 用什么工具可以查出内存泄露 (1)MerroyAnalyzer:一个功能丰富的java堆转储文件分析工具,可以 ...
- 剑指Offer——知识点储备-J2EE基础
剑指Offer--知识点储备-J2EE基础 9.2 jdk 1.8的新特性(核心是Lambda 表达式) 参考链接:http://www.bubuko.com/infodetail-690646.ht ...
- 剑指Offer——迅雷笔试题+知识点总结
剑指Offer--迅雷笔试题+知识点总结 情景回顾 时间:2016.9.19 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:迅雷笔试 总体来说,迅雷笔试内容体量不算多,主要 ...
- 剑指Offer——携程笔试题+知识点总结
剑指Offer--携程笔试题+知识点总结 情景回顾 时间:2016.9.17 19:10-21:10 地点:山东省网络环境智能计算技术重点实验室 事件:携程笔试 总体来说,携程笔试内容与其它企业笔试题 ...
- 剑指Offer——归并排序思想应用
剑指Offer--归并排序思想应用 前言 在学习排序算法时,初识归并排序,从其代码量上感觉这个排序怎么这么难啊.其实归并排序的思想很简单:将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列 ...
- 剑指Offer——巧妙使用sort(List<T>,Comparator<? super T>)比较器
剑指Offer--巧妙使用sort(List<T>,Comparator<? super T>)比较器 先入为主 package cn.edu.ujn.offersword; ...
随机推荐
- linux内核中的链表
1.内核中的链表 linux内核链表与众不同,他不是把将数据结构塞入链表,而是将链表节点塞入数据,在2.1内核中引入了官方链表,从此内核中所有的链表使用都采用此链表,千万不要在重复造车轮子了!链表实现 ...
- 2015 多校联赛 ——HDU5334(构造)
Virtual Participation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Ot ...
- 用js来实现那些数据结构11(字典)
我们这篇文章来说说Map这种数据结构如何用js来实现,其实它和集合(Set)极为类似,只不过Map是[键,值]的形式存储元素,通过键来查询值,Map用于保存具有映射关系的数据,Map里保存着两组数据: ...
- springboot集成redis(mybatis、分布式session)
安装Redis请参考:<CentOS快速安装Redis> 一.springboot集成redis并实现DB与缓存同步 1.添加redis及数据库相关依赖(pom.xml) <depe ...
- Unique-paths (动态规划)
题目描述 A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below) ...
- Chinese-Text-Classification,用卷积神经网络基于 Tensorflow 实现的中文文本分类。
用卷积神经网络基于 Tensorflow 实现的中文文本分类 项目地址: https://github.com/fendouai/Chinese-Text-Classification 欢迎提问:ht ...
- Linux下双网卡Firewalld的配置流程
实验室拟态存储的项目需要通过LVS-NAT模式通过LVS服务器来区隔内外网的服务,所以安全防护的重心则落在了LVS服务器之上.笔者最终选择通过firewalld放行端口的方式来实现需求,由于firew ...
- Java web 前端面试知识点总结
经过几家大厂面试,目前成功拿到唯品会offer,分享一下我的面试知识点总结: 耦合性:也称块间联系.指软件系统结构中各模块间相互联系紧密程度的一种度量.模块之间联系越紧密,其耦合性就越强,模块的独立性 ...
- 学习sharding-jdbc 分库分表扩展框架
先丢代码地址 https://gitee.com/a247292980/sharding-jdbc 再丢pom.xml的dependency <properties> <projec ...
- [原创]基于VueJs的前后端分离框架搭建之完全攻略
首先请原谅本文标题取的有点大,但并非为了哗众取宠.本文取这个标题主要有3个原因,这也是写作本文的初衷: (1)目前国内几乎搜索不到全面讲解如何搭建前后端分离框架的文章,讲前后端分离框架思想的就更少了, ...