Java实现图的遍历(深搜与广搜)

来源:互联网 发布:java 软件工程师 编辑:程序博客网 时间:2024/05/17 06:53


本文以邻接矩阵作为存储结构,用Java实现图的遍历,话不多说,先给出的图的结构,如下: 

1、深度优先搜索遍历 
思想: 
沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。(百度百科)

代码如下:

package com.ds.graph;public class DFSTraverse {    // 构造图的边    private int[][] edges = { { 0, 1, 0, 0, 0, 1, 0, 0, 0 },            { 1, 0, 1, 0, 0, 0, 1, 0, 1 }, { 0, 1, 0, 1, 0, 0, 0, 0, 1 },            { 0, 0, 1, 0, 1, 0, 1, 1, 1 }, { 0, 0, 0, 1, 0, 1, 0, 1, 0 },            { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0, 1, 0, 1, 0 },            { 0, 0, 0, 1, 1, 0, 1, 0, 0 }, { 0, 1, 1, 1, 0, 0, 0, 0, 0 } };    // 构造图的顶点    private String[] vertexs = { "A", "B", "C", "D", "E", "F", "G", "H", "I" };    // 记录被访问顶点    private boolean[] verStatus;    // 顶点个数    private int vertexsNum = vertexs.length;    public void DFSTra() {        verStatus = new boolean[vertexsNum];        for (int i = 0; i < vertexsNum; i++) {            if (verStatus[i] == false) {                DFS(i);            }        }    }    // 递归深搜    private void DFS(int i) {        System.out.print(vertexs[i] + " ");        verStatus[i] = true;        for (int j = firstAdjVex(i); j >= 0; j = nextAdjvex(i, j)) {            if (!verStatus[j]) {                DFS(j);            }        }    }    // 返回与i相连的第一个顶点    private int firstAdjVex(int i) {        for (int j = 0; j < vertexsNum; j++) {            if (edges[i][j] > 0) {                return j;            }        }        return -1;    }    // 返回与i相连的下一个顶点    private int nextAdjvex(int i, int k) {        for (int j = (k + 1); j < vertexsNum; j++) {            if (edges[i][j] == 1) {                return j;            }        }        return -1;    }    // 测试    public static void main(String[] args) {        new DFSTraverse().DFSTra();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

2、广度优先搜索遍历 
思想: 
从根节点开始,沿着树的宽度、按照层次依次遍历树的节点;

代码如下:

package com.ds.graph;import java.util.LinkedList;import java.util.Queue;public class BFSTraverse_0100 {    // 构造图的边    private int[][] edges = { { 0, 1, 0, 0, 0, 1, 0, 0, 0 },            { 1, 0, 1, 0, 0, 0, 1, 0, 1 }, { 0, 1, 0, 1, 0, 0, 0, 0, 1 },            { 0, 0, 1, 0, 1, 0, 1, 1, 1 }, { 0, 0, 0, 1, 0, 1, 0, 1, 0 },            { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0, 1, 0, 1, 0 },            { 0, 0, 0, 1, 1, 0, 1, 0, 0 }, { 0, 1, 1, 1, 0, 0, 0, 0, 0 } };    // 构造图的顶点    private String[] vertexs = { "A", "B", "C", "D", "E", "F", "G", "H", "I" };    // 记录被访问顶点    private boolean[] verStatus;    // 顶点个数    private int vertexsNum = vertexs.length;    // 广搜    private void BFS() {        verStatus = new boolean[vertexsNum];        Queue<Integer> temp = new LinkedList<Integer>();        for (int i = 0; i < vertexsNum; i++) {            if (!verStatus[i]) {                System.out.print(vertexs[i] + " ");                verStatus[i] = true;                temp.offer(i);                while (!temp.isEmpty()) {                    int j = temp.poll();                    for (int k = firstAdjvex(j); k >= 0; k = nextAdjvex(j, k)) {                        if (!verStatus[k]) {                            System.out.print(vertexs[k] + " ");                            verStatus[k] = true;                            temp.offer(k);                        }                    }                }            }        }    }    // 返回与i相连的第一个顶点    private int firstAdjvex(int i) {        for (int j = 0; j < vertexsNum; j++) {            if (edges[i][j] > 0) {                return j;            }        }        return -1;    }    // 返回与i相连的下一个顶点    private int nextAdjvex(int i, int k) {        for (int j = (k + 1); j < vertexsNum; j++) {            if (edges[i][j] > 0) {                return j;            }        }        return -1;    }    // 测试    public static void main(String args[]) {        new BFSTraverse_0100().BFS();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68



[java] view plain copy
  1. import java.util.*;  
  2.   
  3. /** 
  4.   *  这个例子是图的遍历的两种方式 
  5.   *  通过它,使我来理解图的遍历  
  6.   *  Created on 2013-11-18 
  7.   *  @version 0.1 
  8.   */  
  9. public class DeptSearch  
  10. {  
  11.     public static void main(String args[]){  
  12.         //构造需要点对象  
  13.         NodeT a=new NodeT("a");  
  14.         NodeT b=new NodeT("b");  
  15.         NodeT c=new NodeT("c");  
  16.         NodeT d=new NodeT("d");  
  17.         NodeT e=new NodeT("e");  
  18.         NodeT f=new NodeT("f");  
  19.         NodeT g=new NodeT("g");  
  20.         NodeT h=new NodeT("h");  
  21.         ArcT ab=new ArcT(a,b);  
  22.         ArcT ac=new ArcT(a,c);  
  23.         ArcT ad=new ArcT(a,d);  
  24.         ArcT ah=new ArcT(a,h);  
  25.         ArcT bc=new ArcT(b,c);  
  26.         ArcT de=new ArcT(d,e);  
  27.         ArcT ef=new ArcT(e,f);  
  28.         ArcT eg=new ArcT(e,g);  
  29.         ArcT hg=new ArcT(h,g);  
  30.   
  31.         //建立它们的关系  
  32.         a.outgoing.add(ab);  
  33.         a.outgoing.add(ac);  
  34.         a.outgoing.add(ad);  
  35.         a.outgoing.add(ah);  
  36.         b.outgoing.add(bc);  
  37.         d.outgoing.add(de);  
  38.         e.outgoing.add(ef);  
  39.         e.outgoing.add(eg);  
  40.         h.outgoing.add(hg);  
  41.   
  42.         //构造本对象  
  43.         DeptSearch search=new DeptSearch();  
  44.           
  45.         //广度遍历  
  46.         System.out.println("广度遍历如下:");  
  47.         search.widthSearch(a);  
  48.   
  49.         //深度遍历  
  50.         System.out.println("深度遍历如下:");  
  51.         List<NodeT> visited=new ArrayList<NodeT>();  
  52.         search.deptFisrtSearch(a,visited);  
  53.           
  54.     }  
  55.       
  56.     /* 
  57.      * 深度排序的方法 
  58.      * 这个方法的方式:按一个节点,一直深入的找下去,直到它没有节点为止 
  59.      * cur  当前的元素 
  60.      * visited 访问过的元素的集合 
  61.      */  
  62.     void deptFisrtSearch(NodeT cur,List<NodeT> visited){  
  63.         //被访问过了,就不访问,防止死循环  
  64.         if(visited.contains(cur)) return;  
  65.         visited.add(cur);  
  66.         System.out.println("这个遍历的是:"+cur.word);  
  67.         for(int i=0;i<cur.outgoing.size();i++){  
  68.             //访问本点的结束点  
  69.             deptFisrtSearch(cur.outgoing.get(i).end,visited);  
  70.         }  
  71.     }  
  72.   
  73.     /** 
  74.      * 广度排序的方法 
  75.      * 这个方法的方式:按层次对图进行访问,先第一层,再第二层,依次类推 
  76.      * @param start 从哪个开始广度排序 
  77.      */  
  78.     void widthSearch(NodeT start){  
  79.         //记录所有访问过的元素  
  80.         Set<NodeT> visited=new HashSet<NodeT>();  
  81.         //用队列存放所有依次要访问元素  
  82.         Queue<NodeT> q=new LinkedList<NodeT>();  
  83.         //把当前的元素加入到队列尾  
  84.         q.offer(start);  
  85.           
  86.         while(!q.isEmpty()){  
  87.             NodeT cur=q.poll();  
  88.             //被访问过了,就不访问,防止死循环  
  89.             if(!visited.contains(cur)){  
  90.                 visited.add(cur);  
  91.                 System.out.println("查找的节点是:"+cur.word);  
  92.                 for(int i=0;i<cur.outgoing.size();i++){  
  93.                     //把它的下一层,加入到队列中  
  94.                     q.offer(cur.outgoing.get(i).end);  
  95.                 }  
  96.             }  
  97.         }  
  98.     }  
  99.   
  100. }  
  101.   
  102. /** 
  103.   * 图的点 
  104.   */  
  105. class NodeT  
  106. {  
  107.     /* 点的所有关系的集合 */  
  108.     List<ArcT> outgoing;  
  109.     //点的字母  
  110.     String word;  
  111.     public NodeT(String word){  
  112.         this.word=word;  
  113.         outgoing=new ArrayList<ArcT>();  
  114.     }  
  115. }  
  116.   
  117. /** 
  118.   * 单个图点的关系 
  119.   */  
  120. class ArcT  
  121. {  
  122.     NodeT start,end;/* 开始点,结束点 */  
  123.     public ArcT(NodeT start,NodeT end){  
  124.         this.start=start;  
  125.         this.end=end;  
  126.     }  
  127. }  


 


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩发烧37.8度怎么办 坐火车没有座位怎么办 小孩坐火车饮食怎么办 飞机托运了手机怎么办 飞机随身包超重怎么办 行李超过20公斤怎么办 飞机安检有钢板怎么办 飞机上拍照片怎么办? 飞机行李超重该怎么办 无法买机票出行怎么办 机票的保险发票怎么办 行李办理托运后怎么办 飞机托运超尺寸怎么办 机票无托运行李怎么办 飞机票不含托运怎么办 登机重量超了怎么办 随身行李超重了怎么办 国际航班没带护照怎么办 派出所不开户籍怎么办 做火车没身份证怎么办 2018年怎么办户籍证明 一岁宝宝护照怎么办 户籍证明开不了怎么办 信用卡提不了额怎么办 信用卡提额诈骗怎么办 信用卡提额失败怎么办 身份证证件号错误怎么办 东西落在飞机上怎么办 乘高铁忘记带身份证怎么办 身份证丢坐火车怎么办 苏州市民a卡怎么办 集体户口户口页怎么办 网上不能买火车票怎么办 集体户口离婚时怎么办 没户口本怎么办结婚证 酒店没带身份证怎么办 住酒店拍身份证怎么办 手机取火车票要怎么办 香港酒店没登记怎么办 住宿未带身份证怎么办 长期住酒店怎么办暂住证