无向图创建 Undirected Graphs, 深度优先 DFS    DepthFirstSearch_graph

* Graph.java

package com.merrytech;

import java.util.HashMap;
import java.util.Map;
import java.util.LinkedList;
import java.util.Set;

public class Graph<E> {
    private final int v; // number of vertices
    private int e; // number of edges
    private final HashMap<E, LinkedList<E>> adj; // adjacency lists

    public Graph(int v) {
        this.v = v;
        this.e = 0;
        this.adj = new HashMap<>(v);
    }

    public int countV() { return this.v; }
    public int countE() { return this.e; }

    public void addEdge(E v, E w) {
        this.adj.computeIfAbsent(v, k -> new LinkedList<>());
        this.adj.computeIfAbsent(w, k -> new LinkedList<>());
        this.adj.get(v).add(w);
        this.adj.get(w).add(v);
        this.e += 1;
    }

    public LinkedList<E> getAdjList(E v) {
        return this.adj.get(v);
    }

    public Set<E> getVertices() {
        return this.adj.keySet();
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(this.v).append(" vertices, ").append(this.e).append(" edges\n");
        for (Map.Entry<E, LinkedList<E>> entry : this.adj.entrySet()) {
            sb.append(entry.getKey().toString()).append(": ");
            for (E w : entry.getValue()) {
                sb.append(w.toString()).append(" ");
            }
            sb.append("\n");
        }
        return sb.toString();
    }

    public int degree(E v) {
        int degree = 0;
        for (E w : this.getAdjList(v)) {
            degree += 1;
        }
        return degree;
    }

    public int maxDegree() {
        int max = 0;
        int thisDegree = 0;
        for (E v : this.getVertices()) {
            thisDegree = this.degree(v);
            if (thisDegree > max) {
                max = thisDegree;
            }
        }
        return max;
    }

    public double avgDegree() {
        return 2.0 * this.countE() / this.countV();
    }

    public int numberOfSelfLoops() {
        int count = 0;
        for (E v : this.getVertices()) {
            for (E w : this.getAdjList(v)) {
                // System.out.printf("v=%s,w=%s\n", v, w);
                if (v.equals(w)) {
                    count += 1;
                }
            }
        }
        return count / 2;
    }
}

* Main.java

package com.merrytech;

public class Main {

    public static void main(String[] args) {
	// write your code here
        Graph<String> graph = new Graph<>(7);
        graph.addEdge("A", "B");
        graph.addEdge("A", "C");
        graph.addEdge("A", "F");
        graph.addEdge("A", "G");
        graph.addEdge("D", "E");
        graph.addEdge("D", "F");
        graph.addEdge("E", "F");
        graph.addEdge("E", "G");
        // self loops edges
        graph.addEdge("A", "A");
        graph.addEdge("E", "E");

        System.out.println(graph.toString());

        System.out.printf("Degree of vertex E: %d\n", graph.degree("E")); // 3
        System.out.printf("Degree of vertex A: %d\n", graph.degree("A")); // 4
        System.out.printf("count self-loops=%d\n", graph.numberOfSelfLoops()); // 2
        System.out.printf("Max degree=%d\n", graph.maxDegree()); // 4
        System.out.printf("Average degree=%.3f\n", graph.avgDegree());
    }
}

 

无向图创建 Undirected Graphs, 深度优先 DFS    DepthFirstSearch_测试数据_02

JDK 1.8

领接表 LinkedList换成HashSet, 就不会有重复的边。

 

深度优先 DFS

无向图创建 Undirected Graphs, 深度优先 DFS    DepthFirstSearch_测试数据_03

* DepthFirstSearch.java

package com.merrytech;

import java.util.HashMap;

public class DepthFirstSearch<K> {
    private HashMap<K, Boolean> marked;
    private int count;

    public DepthFirstSearch(Graph<K> g, K s, Handler<K> h) {
        this.count = 0;
        this.marked = new HashMap<>();
        this.dfs(g, s, h);
    }

    private void dfs(Graph<K> g, K v, Handler<K> h) {
        this.marked.put(v, true);
        count += 1;
        for (K w : g.getAdjList(v)) {
            if (!this.marked.containsKey(w)) {
                this.dfs(g, w, h);
            }
        }
        h.visit(v);
    }

    public boolean marked(K w) { return this.marked.containsKey(w); }

    public int count() {return this.count;}
}

* Handler.java

package com.merrytech;

public class Handler<E> {
    public Handler() {}

    public void visit(E e) {
        System.out.print(e + " ");
    }
}

* Main.java

改写主类

package com.merrytech;

public class Main {

    public static void main(String[] args) {
        Graph<Integer> graph = new Graph<>(6);
        graph.addEdge(0, 2);
        graph.addEdge(0, 1);
        graph.addEdge(1, 2);
        graph.addEdge(3, 5);
        graph.addEdge(3, 4);
        graph.addEdge(3, 2);
        graph.addEdge(2, 4);
        graph.addEdge(5, 0);

        System.out.println(graph.toString());

        new DepthFirstSearch<>(graph, 0, new Handler<>());
        System.out.println();
    }
}

无向图创建 Undirected Graphs, 深度优先 DFS    DepthFirstSearch_graph_04

marked[]   TreeMap  Key需要传Comparable, 比较Key大小关系,用HashMap算了。

adj[]          用HashSet自动从小到大排序,为了与示例测试数据一致,用LinkedList

下一篇: 图中深度优先路径 Depth-first search to find paths in a graph