这里采用的是邻接表的表示,代码如下:

邻接表

package adjecentList;

import java.util.ArrayList;
import java.util.List;

public class AdjecentList {

private List<Node> nodes = new ArrayList<Node>();

public List<Node> getNodes() {
return nodes;
}

public void addNode(Node node){
nodes.add(node);
}

public Node findNode(String info){
for(Node node : nodes){
if (node.getInfo().equals(info)) {
return node;
}
}
return null;
}

public Node findFirst(){
if (nodes != null) {
return nodes.get(0);
}
return null;
}
}


边:

package adjecentList;

public class Edge {

private Node front;
private Node back;
private Edge next;

public Node getFront() {
return front;
}
public Node getBack() {
return back;
}
public void setFront(Node front) {
this.front = front;
}
public void setBack(Node back) {
this.back = back;
}
public String toString() {
String s = "" + front.getInfo() + "-" + back.getInfo();
return s;
}
public Edge getNext() {
return next;
}
public void setNext(Edge next) {
this.next = next;
}
}

点:

package adjecentList;

public class Node {

private String info;
private Edge nextEdge;

public String getInfo() {
return info;
}

public void setInfo(String info) {
this.info = info;
}

public Edge getNextEdge() {
return nextEdge;
}

public void addEdge(Edge edge){
if (this.getNextEdge() == null)
this.nextEdge = edge;
else {
Edge p = this.getNextEdge();
while(p.getNext() != null)
p = p.getNext();
p.setNext(edge);
}
}

}


算法:

package algorithm;

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

import adjecentList.AdjecentList;
import adjecentList.Edge;
import adjecentList.Node;
import tool.IOTool;

/**
* 未做输入格式检测
* @author miracle
*
*/
public class AlgorithmTool {

private static String INPUT_NODE = "please input the node set: ";
private static String INPUT_EDGE = "please input the edge set: ";

public static void breadthFirstSearch(AdjecentList graph){
Map<Node, Integer> visited = createVisit(graph);
List<Edge> eSet = new ArrayList<Edge>();
Node first = null;
for(Node node : graph.getNodes()){
if (visited.get(node) == 0) {
first = node;
break;
}
}
if (first == null)
return;
List<Node> queue = new ArrayList<>();
queue.add(first);
while(!queue.isEmpty()){
Node queueNode = queue.get(0);
queue.remove(0);
visited.put(queueNode, 1);

Edge edge = queueNode.getNextEdge();
while (edge != null) {
Node back = edge.getBack();
if (visited.get(back) == 0) {
eSet.add(edge);
visited.put(back, 1);
queue.add(back);
}
edge = edge.getNext();
}
}
IOTool.print("DFS edges: ");
for(Edge edge : eSet){
System.out.println(edge);
}
}

public static void depthFirstSearch(AdjecentList graph){
Map<Node, Integer> visited = createVisit(graph);
List<Edge> eSet = new ArrayList<Edge>();
Node first = null;
for(Node node : graph.getNodes()){
if (visited.get(node) == 0) {
first = node;
break;
}
}
if (first != null) {
DFS(first, visited, eSet);
}

IOTool.print("DFS edges: ");
for(Edge edge : eSet){
System.out.println(edge);
}
}

private static void DFS(Node node, Map<Node, Integer> visited, List<Edge> eSet){
visited.put(node, 1);
Edge edge = node.getNextEdge();
while(edge != null){
Node back = edge.getBack();
if (visited.get(back) == 0) {
eSet.add(edge);
DFS(back,visited,eSet);
}
edge = edge.getNext();
}
}

private static Map<Node, Integer> createVisit(AdjecentList graph){
Map<Node, Integer> visited = new HashMap<Node, Integer>();
for(Node node : graph.getNodes()){
visited.put(node, 0);
}
return visited;
}

public static AdjecentList createGraph(){
//输入点集
IOTool.print(INPUT_NODE);
String nodeStr = IOTool.getInput();
String []nodeArray = nodeStr.split(",");

AdjecentList graph = new AdjecentList();
for(String nodeInfo : nodeArray){
Node node = new Node();
node.setInfo(nodeInfo);
graph.addNode(node);
}
//输入边集
IOTool.print(INPUT_EDGE);
String edgeStr = IOTool.getInput();
String []edgeArray = edgeStr.split(",");
for(String edgeInfo : edgeArray){
String []pair = edgeInfo.split("-");
String frontNode = pair[0];
String backNode = pair[1];

Node front = graph.findNode(frontNode);
Node back = graph.findNode(backNode);
if (front != null && back != null) {
Edge edge = new Edge();
edge.setFront(front);
edge.setBack(back);
front.addEdge(edge);
}
}
return graph;
}
}


io:

package tool;

import java.util.Scanner;

public class IOTool {

public static String getInput() {
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
return input;
}

public static void print(String s) {
System.out.println(s);
}
}


main:

package main;

import adjecentList.AdjecentList;
import algorithm.AlgorithmTool;

public class Main {

public static void main(String[] args) {
AdjecentList graph = AlgorithmTool.createGraph();
AlgorithmTool.depthFirstSearch(graph);
AlgorithmTool.breadthFirstSearch(graph);
}

}


如果采用邻接表,那么dfs时间复杂度为O(m+n),终于在书上找到一个特别在理的解释了。

把算法分为2部分:

1建立visit数组,用 O(n)

2找邻接点,总共是每一个点的度的和,明显为O(2m)。具体说就是对每一个点而言,它的每一个未访问过的邻接点要执行一次dfs操作。所以dfs的总数不会超过2m。

相加即可。