剑指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; ...
随机推荐
- [SHOI2008]汉诺塔
Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上, 大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的 ...
- 洛谷P1446 [HNOI2008]Cards
置换群+dp #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring& ...
- 【BZOJ3631】【JLOI2014】松鼠的新家
原题传送门 题意:给你一棵树,然后有一个遍历顺序,你需要补全这个遍历顺序,然后输出这个遍历顺序中每个点的出现次数. 解题思路:本来想找树剖的题,结果发现了一题可以直接写lca的.... 做法1:非常简 ...
- Atom 编辑器安装 linter-eslint 插件,并配置使其支持 vue 文件中的 js 格式校验
安装方式有如下几种. 1.最常用的安装方式. # 进入atom插件文件夹 cd ~/.atom/packages/ # git clone 插件源文件 git clone https://github ...
- selenium常用内容
一.声明浏览器对象 注意点一,Python文件名或者包名不要命名为selenium,会导致无法导入 from selenium import webdriver #webdriver可以认为是浏览器的 ...
- easing--缓动函数--贝塞尔函数--圆盘转动抽奖应用
http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js http://www.robertpenner.com/easing/penn ...
- 【转载】RAID写惩罚(Write Penalty)与IOPS计算
浅谈RAID写惩罚(Write Penalty)与IOPS计算 Character is what you are in the dark. 暗处最能反映一个人真正品格. ---------Apri ...
- ACM Strange fuction
现在,这里有一个功能: F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100) 当x在0到100之间时,你能找到最小值吗? 输入 第一行包 ...
- 异步请求引发的Chrome死锁
浏览器支持的并发异步请求数目是有限的,当需要的资源过多时候(远远大于并发数目),就需要自己管理XHR请求. 在实现自己的XHR的Manger时候,当请求数目达到2000多的时候,经常会遇到chrome ...
- [BBS]搭建开源论坛之Jforum搭配开源CKEDITOR
本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/47946065 使用默认的编辑器的时候,格式都无法保 ...