Java实现无向图的邻接列表表示,深度遍历及广度遍历

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java实现无向图的邻接列表表示,深度遍历及广度遍历相关的知识,希望对你有一定的参考价值。

1. 图的表示

图用 G = (V,E)表示。V表示顶点集,E表示每条边。

n = |V|, m = |E|, 表示有 n个顶点,m条边。

顶点n 与 边数m 的关系:m ——(n-1 ~ n^2)之间;

2. 图的分类

图根据边有无方向,分为有向图、无向图;

图根据顶点数与边数的关系,分为稀疏图、稠密图。

顶点数n与边数m大致呈线性关系的为稀疏图,顶点数n与边数m大致呈平方关系的为稠密图(m~n^2)。

3. 图的表示

可以用邻接列表、邻接矩阵来表示图。

稀疏图一般用邻接列表(占用空间大致为m+n),稠密图用邻接矩阵表示(占用空间为n^2,稀疏图如果用邻接矩阵表示太浪费空间,所以邻接矩阵一般只表示小的稀疏图或者稠密图)。

4. 图的遍历

宽度优先、深度优先遍历

  • 宽度优先遍历 BFS Breadth First Search
  • 深度优先遍历 DFS Depth First Search

示例图A:
在这里插入图片描述
示例图B:
在这里插入图片描述

5. 源码

遍历结果效果图:
在这里插入图片描述

5.1 图的邻接列表表示

package graph;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*************************************
 *Class Name: Graph
 *Description: <图的邻接列表表示方法>
 *@author: Seminar
 *@create: 2021/5/11
 *@since 1.0.0
 *************************************/
public class Graph {

    private List<String> vList;
    private Map<String, List<String>> eList;

    public Graph(List<String> vList, Map<String, List<String>> eList) {
        this.vList = vList;
        this.eList = eList;
    }

    public List<String> getvList() {
        return vList;
    }

    public Map<String, List<String>> geteList() {
        return eList;
    }

    public static Graph initA() {
        List<String> vList = new ArrayList();
        Map<String, List<String>> eList = new HashMap();
        vList.add("s");
        vList.add("a");
        vList.add("b");
        vList.add("c");
        vList.add("d");
        vList.add("e");

        List<String> sList = new ArrayList<>();
        sList.add("a");
        sList.add("b");
        eList.put("s", sList);
        List<String> aList = new ArrayList<>();
        aList.add("s");
        aList.add("c");
        eList.put("a", aList);
        List<String> bList = new ArrayList<>();
        bList.add("s");
        bList.add("c");
        bList.add("d");
        eList.put("b", bList);
        List<String> cList = new ArrayList<>();
        cList.add("a");
        cList.add("b");
        cList.add("d");
        cList.add("e");
        eList.put("c", cList);
        List<String> dList = new ArrayList<>();
        dList.add("b");
        dList.add("c");
        dList.add("e");
        eList.put("d", dList);
        List<String> e1List = new ArrayList<>();
        e1List.add("c");
        e1List.add("d");
        eList.put("e", e1List);

        return new Graph(vList, eList);
    }

    public static Graph initB() {
        List<String> vList = new ArrayList();
        Map<String, List<String>> eList = new HashMap();
        vList.add("1");
        vList.add("2");
        vList.add("3");
        vList.add("4");
        vList.add("5");
        vList.add("6");
        vList.add("7");
        vList.add("8");

        List<String> oneList = new ArrayList<>();
        oneList.add("2");
        oneList.add("3");
        eList.put("1", oneList);
        List<String> twoList = new ArrayList<>();
        twoList.add("1");
        twoList.add("4");
        twoList.add("5");
        eList.put("2", twoList);
        List<String> threeList = new ArrayList<>();
        threeList.add("1");
        threeList.add("6");
        threeList.add("7");
        eList.put("3", threeList);
        List<String> fourList = new ArrayList<>();
        fourList.add("2");
        fourList.add("8");
        eList.put("4", fourList);
        eList.put("5", fourList);
        List<String> sixList = new ArrayList<>();
        sixList.add("3");
        eList.put("6", sixList);
        eList.put("7", sixList);
        List<String> eightList = new ArrayList<>();
        eightList.add("4");
        eightList.add("5");
        eList.put("8", eightList);

        return new Graph(vList, eList);
    }
}

5.1 邻接列表宽度优先、深度优先遍历

package graph;

import java.util.*;

/*************************************
 *Class Name: GenericSearch
 *Description: <基本遍历查找>
 *@author: Seminar
 *@create: 2021/5/11
 *@since 1.0.0
 *************************************/
public class GenericSearch {

    /**
     * Breadth First Search 宽度优先遍历
     *
     * @param graph 无向图
     * @param first 起点
     */
    public static void BFS(Graph graph, String first) {
        // 宽度优先遍历
        Queue<String> queue = new ArrayDeque<>();
        queue.add(first);

        Map<String, Boolean> map = new HashMap<>();
        for (String str : graph.getvList()) {
            map.put(str, Boolean.FALSE);
        }

        String bfsStr = "BFS: ";
        while (queue.size() > 0) {
            String v = queue.poll();
            if (map.get(v) == Boolean.TRUE) {
                continue;
            }
            bfsStr += v + " -> ";
//            System.out.print(v + " -> ");
            // 标记为“已探索”
            map.put(v, Boolean.TRUE);
            for (String w : graph.geteList().get(v)) {
                queue.add(w);
            }
        }
        System.out.println(bfsStr.substring(0, bfsStr.length() - 4));
    }

    /**
     * Depth First Search 深度优先遍历
     *
     * @param graph 无向图
     * @param first 起点
     */
    public static void DFS(Graph graph, String first) {
        Queue<String> queue = new ArrayDeque<>();
        queue.add(first);
        Deque<String> deque = new ArrayDeque<>();
        deque.add(first);

        Map<String, Boolean> map = new HashMap<>();
        for (String str : graph.getvList()) {
            map.put(str, Boolean.FALSE);
        }

        // 深度优先遍历
        String dfsStr = "DFS: ";
        String vv = "";
        while (deque.size() > 0) {
            vv = deque.poll();
            for (String w : graph.geteList().get(vv)) {
                while (queue.size() > 0) {
                    vv = queue.poll();
                    if (map.get(vv) == Boolean.TRUE) {
                        continue;
                    }
                    dfsStr += vv + " -> ";
//                    System.out.println(vv);
                    // 标记为“已探索”
                    map.put(vv, Boolean.TRUE);
                    for (String w1 : graph.geteList().get(vv)) {
                        if (map.get(w1) == Boolean.TRUE) {
                            continue;
                        }
                        queue.add(w1);
                        deque.add(w1);
                        break;
                    }
                }
                if (map.get(w) == Boolean.TRUE) {
                    continue;
                } else {
                    queue.add(w);
                    deque.add(w);
                }
            }
        }
        System.out.println(dfsStr.substring(0, dfsStr.length() - 4));
    }

    public static void main(String[] args) {
        Graph graphA = Graph.initA();
        String first = "s";
        System.out.println("图A:");
        BFS(graphA, first);
        DFS(graphA, first);

        System.out.println();

        Graph graphB = Graph.initB();
        first = "1";
        System.out.println("图B:");
        BFS(graphB, first);
        DFS(graphB, first);
    }
}

以上是关于Java实现无向图的邻接列表表示,深度遍历及广度遍历的主要内容,如果未能解决你的问题,请参考以下文章

图的表示深度广度遍历算法及其应用

存储结构与邻接矩阵,深度优先和广度优先遍历及Java实现

c语言图的遍历,邻接表存储,深度,广度优先遍历

用c语言编程 1创建图的邻接矩阵和邻接表 2验证图的深度优先、广度优先遍历算法 3验证最短路径

求算法,用邻接矩阵和邻接表创建一个图,实现深度和广度搜索,菜单形式,c语言的代码。无向无权的图。

给定一个无向图的邻接矩阵的图,要怎么遍历(深度和广度遍历)这个矩阵图,求方法啊