Java实现算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)
对算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)用Java实现其中的伪代码算法,案例也采用算法导论中的图。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;public class GraphSearch {final static HashMap<String,LinkedList<String>> DGraph=new HashMap<String,LinkedList<String>>(); //有向图final static HashMap<String,LinkedList<String>> UGraph=new HashMap<String,LinkedList<String>>(); //无向图public static final int MAX_VALUE=2147483647;public static final int MIN_VALUE=-2147483648;public static void main(String [] args) { //邻接表表示,初始化有向图和无向图,图用算法导论中的案例,分别是图22-1和图22-2GraphSearch.initUGraph();GraphSearch.initDGraph(); //BFS广度优先搜索//GraphSearch.BFSUGraph();//GraphSearch.BFSDGraph();//DFS深度优先搜索GraphSearch gs=new GraphSearch();//gs.DFSUGraph();gs.DFSDGraph();}//深度优先搜索//初始化六个顶点的颜色、父顶点、发现距离和结束距离public String[] DDColor = new String[]{"white","white","white","white","white","white"};public int[] DDDis=new int[]{MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE};public int[] DDFin=new int[]{MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE};public String[] DDParent=new String[]{"null","null","null","null","null","null"};public int DDTime=0;//计算发现时间和结束时间public void DFSDGraph(){//有向图深度优先搜索//遍历邻接表Iterator<Entry<String, LinkedList<String>>> iter=DGraph.entrySet().iterator(); while (iter.hasNext() ) {Map.Entry<String, LinkedList<String>> entry = iter.next();String key = entry.getKey();int iKey=Integer.valueOf(key.substring(1))-1;if (DDColor[iKey]=="white") DFSDGraphVisit(key);}}public void DFSDGraphVisit(String key){//无向图深度优先搜索int n=Integer.valueOf(key.substring(1))-1;DDColor[n]="gray";DDTime=DDTime+1;DDDis[n]=DDTime;LinkedList<String> llV=DGraph.get(key);for(int i=0;i<llV.size();i++){String strV=llV.get(i);int m=Integer.valueOf(strV.substring(1))-1;if(DDColor[m]=="white"){DDParent[m]=key;DFSDGraphVisit(strV);}} DDColor[n]="black";DDTime=DDTime+1;DDFin[n]=DDTime;System.out.println("顶点:"+key+"发现时间:"+String.valueOf(DDDis[n])+"结束时间:"+String.valueOf(DDFin[n])+"父顶点:"+DDParent[n]+"当前颜色:"+DDColor[n]);}//初始化五个顶点的颜色、父顶点、发现距离和结束距离public String[] DUColor = new String[]{"white","white","white","white","white"};public int[] DUDis=new int[]{MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE};public int[] DUFin=new int[]{MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE};public String[] DUParent=new String[]{"null","null","null","null","null"};public int DUTime=0;//计算发现时间和结束时间public void DFSUGraph(){//无向图深度优先搜索 //遍历邻接表Iterator<Entry<String, LinkedList<String>>> iter=UGraph.entrySet().iterator(); while (iter.hasNext() ) {Map.Entry<String, LinkedList<String>> entry = iter.next();String key = entry.getKey();int iKey=Integer.valueOf(key.substring(1))-1;if (DUColor[iKey]=="white") DFSUGraphVisit(key);}}public void DFSUGraphVisit(String key){//无向图深度优先搜索int n=Integer.valueOf(key.substring(1))-1;DUColor[n]="gray";DUTime=DUTime+1;DUDis[n]=DUTime;LinkedList<String> llV=UGraph.get(key);for(int i=0;i<llV.size();i++){String strV=llV.get(i);int m=Integer.valueOf(strV.substring(1))-1;if(DUColor[m]=="white"){DUParent[m]=key;DFSUGraphVisit(strV);}} DUColor[n]="black";DUTime=DUTime+1;DUFin[n]=DUTime;System.out.println("顶点:"+key+"发现时间:"+String.valueOf(DUDis[n])+"结束时间:"+String.valueOf(DUFin[n])+"父顶点:"+DUParent[n]+"当前颜色:"+DUColor[n]);}//广度优先搜索public static void BFSDGraph(){//有向图广度优先搜索//有向图DFS算法要改良,多个源顶点生成多颗树//选初始化六个的颜色、父顶点、最短距离String[] color = new String[]{"white","white","white","white","white","white"};int[] dist=new int[]{MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE};String[] parent=new String[]{"null","null","null","null","null","null"};//遍历顶点表DGraph,看是否还存在未搜索的ArrayList<String> ALV=new ArrayList<String> ();Iterator<Entry<String, LinkedList<String>>> iter=DGraph.entrySet().iterator(); while (iter.hasNext() && ALV.size()<6) {Map.Entry<String, LinkedList<String>> entry = iter.next();String key = entry.getKey();if(ALV.contains(key)) continue;//已搜索,下次循环//LinkedList<String> val = entry.getValue();int iSV=Integer.valueOf(key.substring(1))-1;//初始化源顶点color[iSV]="gray";dist[iSV]=0;parent[iSV]="null";ArrayList<String> queue=new ArrayList<String>();queue.add(key);//开始搜索while(queue.size()>0){String strV=queue.get(0);queue.remove(0);//出列int m=Integer.valueOf(strV.substring(1))-1;LinkedList<String> listV= DGraph.get(strV);for(int i=0;i<listV.size();i++){String strVTmp=listV.get(i);int n=Integer.valueOf(strVTmp.substring(1))-1;//顶点名称第二个字符是数字if(color[n]=="white"){color[n]="gray";dist[n]=dist[m]+1;parent[n]=strV;queue.add(strVTmp);}}color[m]="black";System.out.println("顶点:"+strV+"最短距离:"+String.valueOf(dist[m])+"父顶点:"+parent[m]+"当前颜色:"+color[m]);ALV.add(strV);} }}public static void BFSUGraph(){//无向图广度优先搜索//选择顶点V1为源点,初始化五个的颜色、父顶点、最短距离String[] color = new String[]{"white","white","white","white","white"};int[] dist=new int[]{MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE,MAX_VALUE};String[] parent=new String[]{"null","null","null","null","null"};//初始化源顶点V1color[0]="gray";dist[0]=0;parent[0]="null";ArrayList<String> queue=new ArrayList<String>();queue.add("V1");//开始搜索while(queue.size()>0){String strV=queue.get(0);queue.remove(0);//出列int m=Integer.valueOf(strV.substring(1))-1;LinkedList<String> listV= UGraph.get(strV);for(int i=0;i<listV.size();i++){String strVTmp=listV.get(i);int n=Integer.valueOf(strVTmp.substring(1))-1;//顶点名称第二个字符是数字if(color[n]=="white"){color[n]="gray";dist[n]=dist[m]+1;parent[n]=strV;queue.add(strVTmp);}}color[m]="black";System.out.println("顶点:"+strV+"最短距离:"+String.valueOf(dist[m])+"父顶点:"+parent[m]+"当前颜色:"+color[m]);} }//初始化图 public static void initUGraph(){//无向图初始化//顶点V1的邻接表String strV1="V1";LinkedList<String> ListV1=new LinkedList<String>();ListV1.add("V2");ListV1.add("V5");UGraph.put(strV1, ListV1);//顶点V2的邻接表String strV2="V2";LinkedList<String> ListV2=new LinkedList<String>();ListV2.add("V1");ListV2.add("V5");ListV2.add("V3");ListV2.add("V4");UGraph.put(strV2, ListV2);//顶点V3的邻接表String strV3="V3";LinkedList<String> ListV3=new LinkedList<String>();ListV3.add("V2");ListV3.add("V4");UGraph.put(strV3, ListV3);//顶点V4的邻接表String strV4="V4";LinkedList<String> ListV4=new LinkedList<String>();ListV4.add("V2");ListV4.add("V5");ListV4.add("V3");UGraph.put(strV4, ListV4);//顶点V5的邻接表String strV5="V5";LinkedList<String> ListV5=new LinkedList<String>();ListV5.add("V4");ListV5.add("V1");ListV5.add("V2");UGraph.put(strV5, ListV5);}public static void initDGraph(){//有向图初始化//顶点V1的邻接表String strV1="V1";LinkedList<String> ListV1=new LinkedList<String>();ListV1.add("V2");ListV1.add("V4");DGraph.put(strV1, ListV1);//顶点V2的邻接表String strV2="V2";LinkedList<String> ListV2=new LinkedList<String>();ListV2.add("V5");DGraph.put(strV2, ListV2);//顶点V3的邻接表String strV3="V3";LinkedList<String> ListV3=new LinkedList<String>();ListV3.add("V6");ListV3.add("V5");DGraph.put(strV3, ListV3);//顶点V4的邻接表String strV4="V4";LinkedList<String> ListV4=new LinkedList<String>();ListV4.add("V2");DGraph.put(strV4, ListV4);//顶点V5的邻接表String strV5="V5";LinkedList<String> ListV5=new LinkedList<String>();ListV5.add("V4");DGraph.put(strV5, ListV5);//顶点V6的邻接表String strV6="V6";LinkedList<String> ListV6=new LinkedList<String>();ListV6.add("V6");DGraph.put(strV6, ListV6);/*List arrayList = new ArrayList(DGraph.entrySet());Collections.sort(arrayList, new Comparator() { public int compare(Object arg1, Object arg2) { Map.Entry obj1 = (Map.Entry) arg1; Map.Entry obj2 = (Map.Entry) arg2; return (obj1.getKey()).toString().compareTo((String) obj2.getKey()); } }); //将HASHMAP中的数据排序 for (Iterator iter = arrayList.iterator(); iter.hasNext();) { Map.Entry entry = (Map.Entry)iter.next(); String key = (String)entry.getKey(); System.out.println(key); }*//*Iterator<Entry<String, LinkedList<String>>> iter=DGraph.entrySet().iterator(); while (iter.hasNext() ) {Map.Entry<String, LinkedList<String>> entry = iter.next();System.out.println(entry.getKey());}*/}}
结果:
1)无向图广度优先搜索:
顶点:V1最短距离:0父顶点:null当前颜色:black
顶点:V2最短距离:1父顶点:V1当前颜色:black
顶点:V5最短距离:1父顶点:V1当前颜色:black
顶点:V3最短距离:2父顶点:V2当前颜色:black
顶点:V4最短距离:2父顶点:V2当前颜色:black
2)有向图广度优先搜索
顶点:V2最短距离:0父顶点:null当前颜色:black
顶点:V5最短距离:1父顶点:V2当前颜色:black
顶点:V4最短距离:2父顶点:V5当前颜色:black
顶点:V3最短距离:0父顶点:null当前颜色:black
顶点:V6最短距离:1父顶点:V3当前颜色:black
顶点:V1最短距离:0父顶点:null当前颜色:black
3)无向图深度优先搜索
顶点:V3发现时间:5结束时间:6父顶点:V4当前颜色:black
顶点:V4发现时间:4结束时间:7父顶点:V5当前颜色:black
顶点:V5发现时间:3结束时间:8父顶点:V1当前颜色:black
顶点:V1发现时间:2结束时间:9父顶点:V2当前颜色:black
顶点:V2发现时间:1结束时间:10父顶点:null当前颜色:black
4)有向图深度优先搜索
顶点:V4发现时间:3结束时间:4父顶点:V5当前颜色:black
顶点:V5发现时间:2结束时间:5父顶点:V2当前颜色:black
顶点:V2发现时间:1结束时间:6父顶点:null当前颜色:black
顶点:V6发现时间:8结束时间:9父顶点:V3当前颜色:black
顶点:V3发现时间:7结束时间:10父顶点:null当前颜色:black
顶点:V1发现时间:11结束时间:12父顶点:null当前颜色:black
算法还是有改良空间,比如怎么控制生成树是最大子树。
Java实现算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)相关推荐
- 图论算法(5):图的广度优先遍历 BFS
本章节内容使用 java 实现,Github 代码仓:https://github.com/ZhekaiLi/Code/tree/main/Graph/src 查看文章内的图片可能需要科学上网! 因为 ...
- Java实现算法导论中Miller-Rabin随机性素数测试
Miller-Rabin测试: 费马小定理:对于素数p和任意整数a,有ap ≡ a(mod p)(同余).反过来,满足ap ≡ a(mod p),p也几乎一定是素数. 伪素数:如果n是一个正整数,如果 ...
- Java实现算法导论中Rabin-Karp字符串匹配算法
Rabin-Karp算法的思想: 假设子串的长度为M,目标字符串的长度为N 计算子串的hash值 计算目标字符串中每个长度为M的子串的hash值(共需要计算N-M+1次) 比较hash值 如果hash ...
- Java实现算法导论中朴素字符串匹配算法
朴素字符串匹配算法沿着主串滑动子串来循环匹配,算法时间性能是O((n-m+1)m),n是主串长度,m是字串长度,结合算法导论中来理解,具体代码参考: package cn.ansj;public cl ...
- Java实现算法导论中反复平方法模取幂
在众多的加密算法中都需要进行幂的取模运算,比如在RSA算法中需要计算d=ne mod N,我们称之为幂模算法,其中: N=p*q(p,q为大素数) n为加密数据,n<N e为公钥,d为私钥,满足 ...
- Java实现算法导论中求解模线性方程解(基于最大公约数欧几里得扩展算法)
基于最大公约数欧几里得扩展算法求解算法导论中模线性方程解.具体要结合算法导论中的有关数论算法章节理解,具体代码如下: package cn.ansj;/*假设方程ax=b(mod n)有解,且x0是方 ...
- Java实现算法导论中快速傅里叶变换FFT递归算法
要结合算法导论理解,参考:http://blog.csdn.net/fjssharpsword/article/details/53281889 代码中算法思路:输入n位(2的幂)向量,分别求值FFT ...
- Java实现算法导论中有限自动机字符串匹配算法
这里实现了基于有限自动机(Finite Automaton,FA)的模式匹配算法,算法的重点在于利用字符串的前后缀构造模式P的自动机,具体结合导论中的说明来理解,可参考http://www.geeks ...
- Java实现算法导论中Pollard的rho启发式方法
Pollard的rho启发式方法用于启发式求解大整数n分解因子,具体要结合导论中来理解,参考代码如下: package cn.ansj;import java.math.BigInteger; imp ...
最新文章
- bzoj3295:[CQOI2011]动态逆序对
- 开源与自由 | 商业自由:从边缘到核心贡献
- mysql索引原理剖析
- 如何看打印机的缓存区域_松下打印机好吗 松下打印机卡纸如何解决【详解】...
- 常见的IT自动化运维工具有哪些?推荐一款好用的?
- script 标签中引用asp文件不显示的原因
- 清华大学计算机学教授招,清华大学计算机系网络所刘斌教授招收2015年入学博士生...
- UG NX 12 视图操作
- echarts+3d饼图
- android 屏保程序,Android开发中屏保程序
- Java多线程实现多用户与服务端Socket通信
- server r2 系统更新文件清理
- 云服务器的部署形式之一私有云介绍
- 【设计模式03】 建造者模式
- LiveNVR传统安防摄像机互联网直播-二次开发相关的API接口
- win10 命令行进入指定目录方法
- 【数据结构C语言】二叉树的遍历
- Java对象转xml
- Kumo的目标是让你离不开它!
- 【杂记】火狐浏览器主页被2345恶意篡改解决方法