图的创建


注意:抽象类实现某个接口时,可以不实现接口的所有方法,由它的子类来实现,但是普通类即非抽象类则必须实现接口里的所有方法。

/**
 * 
 */
package com.sunlei;

import java.util.List;

/**
*@author 作者:sunlei
*@version 创建时间:2018年2月27日下午6:47:54
*说明
*/
public interface Graph<T> {
	//返回图中的顶点数
	public int getSize();
	
	//返回图的顶点
	public List<T> getVertices();
	
	//返回指定下标的顶点对象
	public T getVertex(int index);
	
	//返回指定定点的下标
	public int getIndex(T v);
	
	//返回指定下标的顶点的邻居
	public List<Integer> getNeighbors(int index);
	
	//返回指点定点下标的度
	public int getDegree(int v);
	
	//打印边
	public void printEdges();
	
	//清除图
	public void clear();
	
	//添加定点
	public boolean addVertex(T vertex);
	
	//添加边
	public boolean addEdge(int u,int v);
	
	//从顶点v开始一个深度优先搜索树
	public AbstractGraph<T>.Tree dfs(int v);
	
	//从顶点v开始一个广度优先搜索树
	public AbstractGraph<T>.Tree bfs(int v);
}


/**
 * 
 */
package com.sunlei;

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

/**
*@author 作者:sunlei
*@version 创建时间:2018年2月27日下午6:59:31
*说明
*/
public class AbstractGraph<T> implements Graph<T> {
	
	protected List<T> vertices = new ArrayList<>();  //图中的顶点
	protected List<List<Edge>> neighbors = new ArrayList<>(); //图中每个顶点的邻居
	
	//创建一个空图
	protected AbstractGraph() {
		
	}
	
	//从存储在数组中的指定边和顶点构建一个图
	protected AbstractGraph(T[] vertices,int[][] edges) {
		for(int i=0;i<vertices.length;i++) {
			addVertex(vertices[i]);
		}
		createAdjacencyLists(edges,vertices.length);
	}
	
	//从存储在线性表中的指定边和顶点构建一个图
	protected AbstractGraph(List<T> vertices,List<Edge> edges) {
		for(int i=0;i<vertices.size();i++) {
			addVertex(vertices.get(i));
		}
		createAdjacencyLists(edges,vertices.size());
	}
	
	protected AbstractGraph(List<Edge> edges,int numberOfVertices) {
		for(int i=0;i<numberOfVertices;i++) {
			addVertex((T)(new Integer(i)));
		}
		createAdjacencyLists(edges,numberOfVertices);
	}
	
	protected AbstractGraph(int[][] edges,int numberOfVertices) {
		for(int i=0;i<numberOfVertices;i++) {
			addVertex((T)(new Integer(i)));
		}
		createAdjacencyLists(edges,numberOfVertices);
	}
	
	private void createAdjacencyLists(int[][] edges,int numberOfVertices) {
		for(int i=0;i<edges.length;i++) {
			addEdge(edges[i][0],edges[i][1]);
		}
	}
	
	private void createAdjacencyLists(List<Edge> edges,int numberOfVertices) {
		for(Edge edge:edges) {
			addEdge(edge.u,edge.v);
		}
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#getSize()
	 */
	@Override
	public int getSize() {
		// TODO Auto-generated method stub
		return vertices.size();
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#getVertices()
	 */
	@Override
	public List<T> getVertices() {
		// TODO Auto-generated method stub
		return vertices;
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#getVertex(int)
	 */
	@Override
	public T getVertex(int index) {
		// TODO Auto-generated method stub
		return vertices.get(index);
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#getIndex(java.lang.Object)
	 */
	@Override
	public int getIndex(T v) {
		// TODO Auto-generated method stub
		return vertices.indexOf(v);
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#getNeighbors(int)
	 */
	@Override
	public List<Integer> getNeighbors(int index) {
		// TODO Auto-generated method stub
		List<Integer> result = new ArrayList<>();
		for(Edge e:neighbors.get(index))
			result.add(e.v);
		return result;
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#getDegree(int)
	 */
	@Override
	public int getDegree(int v) {
		// TODO Auto-generated method stub
		return neighbors.get(v).size();
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#printEdges()
	 */
	@Override
	public void printEdges() {
		// TODO Auto-generated method stub
		for(int i=0;i<neighbors.size();i++) {
			System.out.print(getVertex(i) + "(" + i + "):");
			for(Edge e:neighbors.get(i)){
				System.out.print("(" + getVertex(e.u) + "," + getVertex(e.v) + ")");
			}
			System.out.println();
		}
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#clear()
	 */
	@Override
	public void clear() {
		// TODO Auto-generated method stub
		vertices.clear();
		neighbors.clear();
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#addVertex(java.lang.Object)
	 */
	@Override
	public boolean addVertex(T vertex) {
		// TODO Auto-generated method stub
		if(!vertices.contains(vertex)) {
			vertices.add(vertex);
			neighbors.add(new ArrayList<Edge>());
			return true;
		}
		else {
			return false;
		}	
	}
	
	protected boolean addEdge(Edge e) {
		if(e.u < 0 || e.u > getSize() - 1) {
			throw new IllegalArgumentException("No such index:" + e.u);
		}
		
		if(e.v < 0 || e.v > getSize() - 1) {
			throw new IllegalArgumentException("No such index:" + e.v);
		}
		
		if(!neighbors.get(e.u).contains(e)) {
			neighbors.get(e.u).add(e);
			return true;
		}
		else {
			return false;
		}
		
	}
	
	/* (non-Javadoc)
	 * @see com.sunlei.Graph#addEdge(int, int)
	 */
	@Override
	public boolean addEdge(int u, int v) {
		// TODO Auto-generated method stub
		return addEdge(new Edge(u,v));
	}
	
	public static class Edge {
		int u;
		int v;
		
		public Edge(int u,int v) {
			this.u = u;
			this.v = v;
		}
		
		public boolean equals(Object o) {
			return u == ((Edge)o).u && v == ((Edge)o).v;
		}

	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#dfs(int)
	 */
	@Override
	public AbstractGraph<T>.Tree dfs(int v) {
		List<Integer> searchOrder = new ArrayList<>();
		int[] parent = new int[vertices.size()];
		for(int i=0;i<parent.length;i++) {
			parent[i] = -1;
		}
		
		boolean[] isVisited = new boolean[vertices.size()];
		
		dfs(v,parent,searchOrder,isVisited);
		
		return new Tree(v,parent,searchOrder);
	}
	
	private void dfs(int u ,int[] parent,List<Integer> searchOrder,boolean[] isVisited) {
		searchOrder.add(u);
		isVisited[u] = true;
		
		for(Edge e : neighbors.get(u)) {
			if(!isVisited[e.u]) {
				parent[e.v] = u;
				dfs(e.v,parent,searchOrder,isVisited);
			}
		}
	}

	/* (non-Javadoc)
	 * @see com.sunlei.Graph#bfs(int)
	 */
	@Override
	public AbstractGraph<T>.Tree bfs(int v) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public class Tree {
		private int root;
		private int[] parent;
		private List<Integer> searchOrder;
		
		public Tree(int root ,int[] parent, List<Integer> searchOrder) {
			this.root = root;
			this.parent = parent;
			this.searchOrder = searchOrder;
		}
		
		public int getRoot() {
			return root;
		}
		
		public int getParent(int v) {
			return parent[v];
		}
		
		public List<Integer> getSearchOrder(){
			return searchOrder;
		}
		
		public int getNumberOfVerticesFound() {
			return searchOrder.size();
		}
		
		public List<T> getPath(int index){
			ArrayList<T> path = new ArrayList<>();
			
			do {
				path.add(vertices.get(index));
				index = parent[index];
			}
			while(index != -1);
			
			return path;
		}
		
		public void printPath(int index) {
			List<T> path = getPath(index);
			System.out.print("A path from " + vertices.get(root) + " to " + vertices.get(index) + ": ");
			for(int i=path.size()-1;i>=0;i--) {
				System.out.print(path.get(i) + " ");
			}
		}
		
		public void printTree() {
			System.out.println("Root is: " + vertices.get(root));
			System.out.print("Edges: ");
			for(int i=0;i<parent.length;i++) {
				if(parent[i] != -1) {
					System.out.print("(" + vertices.get(parent[i]) + "," + vertices.get(i) + ")");
				}
			}
			System.out.println();
		}
	}
}


/**
 * 
 */
package com.sunlei;

import java.util.List;

/**
*@author 作者:sunlei
*@version 创建时间:2018年2月27日下午7:33:49
*说明
*/
public class UnweightedGraph<T> extends AbstractGraph<T> {
	public UnweightedGraph() {
		
	}
	
	public UnweightedGraph(T[] vertices,int[][] edges) {
		super(vertices,edges);
	}
	
	public UnweightedGraph(List<T> vertices,List<Edge> edges) {
		super(vertices,edges);
	}
	
	public UnweightedGraph(List<Edge> edges,int numberOfVertices) {
		super(edges,numberOfVertices);
	}
	
	public UnweightedGraph(int[][] edges,int numberOfVertices) {
		super(edges,numberOfVertices);
	}

}


/**
 * 
 */
package com.sunlei;
/**
*@author 作者:sunlei
*@version 创建时间:2018年2月27日下午6:37:54
*说明
*/
public class TestGraph {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] vertices = {"Wuhan","Chengdu","Hefei","Nanjing","Beijing","Xiamen",
				"Xiantao","Tianmen","Qianjing","Chongqing","Shanghai","Hangzhou"};
		
		int[][] edges = {
				{0,1},{0,3},{0,5},
				{1,0},{1,2},{1,3},
				{2,1},{2,2},{2,4},{2,10},
				{3,0},{3,1},{3,2},{3,4},{3,5},
				{4,2},{4,3},{4,5},{4,7},{4,8},{4,10},
				{5,0},{5,3},{5,4},{5,6},{5,7},
				{6,5},{6,7},
				{7,4},{7,5},{7,6},{7,8},
				{8,4},{8,7},{8,9},{8,10},{8,11},
				{9,8},{9,11},
				{10,2},{10,4},{10,8},{10,11},
				{11,8},{11,9},{11,10}
		};
		
		Graph<String> graph1 = new UnweightedGraph<>(vertices,edges);
		System.out.println("The number of vertices in graph1:" + graph1.getSize());
		System.out.println("The vertex with index 1 is:" + graph1.getVertex(1));
		System.out.println("The index for Xiantao in graph1:" + graph1.getIndex("Xiantao"));
		System.out.println("The edges for graph1:" );
		graph1.printEdges();
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值