第五周作业——有向图邻接表表示及反向图构造

作业要求: 对tinyDG.txt(http://pan.baidu.com/s/1o6jWtcA)文件所表示的图,输出其邻接表表示 与 反向图的邻接表表示。类名GraphReverse

邻接表表示示例如下:

0:1 5

1:

2:0 3

……




在C++中可以用结构体和指针很方便地表示图的邻接表,在java中可以用数组或集合框架来表示.

此处采用Map集合的方式表示邻接表,且顶点的邻接顶点用ArrayList存储,方便查找.

用Java实现有向图的反向图构造,代码如下:

/**
 * 有向图邻接表表示及反向图构造
 */
public class GraphReverse {
	//vertex,顶点数目
	private int v;
	//edge,边数目
	private int e;
	//有向图的邻接表Map集合,key为某顶点,value为该顶点的邻接顶点集合
	private Map<Integer,List<Integer>> adjacencyList;
	//反向图的邻接表Map集合
	private Map<Integer,List<Integer>> adjacencyListReverse;
	
	//初始化
	public GraphReverse(int vertex, int edge){
		if(edge<0) throw new RuntimeException("Number of edges must be nonnegative");
		if (edge > vertex*vertex) throw new RuntimeException("Too many edges");
		
		v = vertex;		
		e = edge;
		
		adjacencyList = new HashMap<Integer,List<Integer>>();
		for(int i=0; i<v; i++){
			adjacencyList.put(i, new ArrayList<Integer>());
		}
		
		adjacencyListReverse = new HashMap<Integer,List<Integer>>();
		for(int i=0; i<v; i++){
			adjacencyListReverse.put(i, new ArrayList<Integer>());
		}
	}
	
	//获取有向图的邻接表
	public Map<Integer,List<Integer>> getAdjacencyList(){
		return adjacencyList;
	}
	//获取反向图的邻接表
	public Map<Integer,List<Integer>> getAdjacencyListReverse(){
		return adjacencyListReverse;
	}
	
	//添加有向图的边
	public void addEdge(int vertex1, int vertex2){
		List<Integer> vList = adjacencyList.get(vertex1);
		vList.add(vertex2);		
	}
	//添加反向图的边
	public void addEdgeReverse(int vertex1, int vertex2){
		List<Integer> vList = adjacencyListReverse.get(vertex1);
		vList.add(vertex2);		
	}
}


测试代码:

	public static void main(String[] args) {
		try(Scanner scanner = new Scanner
				(GraphDAG.class.getClassLoader().getResourceAsStream("tinyDG.txt"));){
				
			//第一行的数字是顶点的数目
			int v = scanner.nextInt();
			//第二行的数字是边的数目
			int e = scanner.nextInt();
			
			//System.err.println(String.format("该有向图的定点数: %d , 边数: %d\n", v, e));
			GraphReverse graphReverse = new GraphReverse(v, e);				
			
			//读取每条边对应的两个顶点,将边添加到图的邻接表里
			for (int i = 0; i < e; i++) {				
				int v1 = scanner.nextInt();
				int v2 = scanner.nextInt();
				graphReverse.addEdge(v1, v2);
				graphReverse.addEdgeReverse(v2, v1);
			}
			
			System.err.println("邻接表表示:");
			printAdjacencyList(graphReverse.getAdjacencyList());
			
			System.err.println("\n反向图的邻接表表示:");
			printAdjacencyList(graphReverse.getAdjacencyListReverse());
				
		}
	}
	
	/**
	 * 打印邻接表
	 * @param adjacencyList
	 */
	public static void  printAdjacencyList(Map<Integer,List<Integer>> adjacencyList){
		for(Map.Entry<Integer,List<Integer>> entry : adjacencyList.entrySet()){
			//某顶点
			int vertex = entry.getKey();
			System.err.print(vertex+":\t");
			
			//该顶点的所有邻接顶点
			List<Integer> vList = entry.getValue();
			if(vList.size()>0){
				for(int v : vList){
					System.err.print(v+"\t");
				}
			}
			System.err.println();
		}
	}


运行结果:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值