【数据结构与算法】图 遍历

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

邻接表

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。

相加即可。

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/u010900754/article/details/52492333
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞