算法笔记13:无向图


本文讲解无向图, 算法笔记14:有向图讲解有向图。

无向图的表示和实现

如下图Graph所示,有一些定点和边组成图,边连接的两个定点相邻,边是对称的,0-1表示可以从0到1,也可以从1到0。从图中可以看到,对于任意一个顶点,都可以有任意多的相邻顶点,我们使用List数组(因为相邻顶点的个数不一致)保存对应索引顶点的相邻顶点,称之为邻接表。下图Graph的邻接表如下:

顶点 相邻顶点
0 1
1 0 2 4
2 1 3
3 2
4 1

在这里插入图片描述
根据邻接表实现Graph

import java.io.*;
import java.util.*;
/**
 * 图
 * @author XY
 *
 */
public class Graph {
   
	private int V;//顶点个数
	private int E;//边的数量
	private ArrayList<Integer>[] adj;//邻接表

	public Graph(int v) {
   //使用顶点个数
		this.V = v;
		adj = (ArrayList<Integer>[]) new ArrayList[this.V];		
		for (int i = 0; i < adj.length; i++) {
   
			adj[i] = new ArrayList<Integer>();
		}
	}
	public Graph(Scanner scanner) throws Exception {
   //根据输入流
		this(scanner.nextInt());
		int numedag=scanner.nextInt();
		for(int i=0;i<numedag;i++){
   
			int v=scanner.nextInt();
			int w=scanner.nextInt();
			addEdage(v, w);
		}

	}
	public void addEdage(int v, int w) {
   //图是对称的,所以一条边要改变两个顶点的list.
		if(v!=w && !adj[v].contains(w)){
   //排除自环和平行边		
		adj[v].add(w);
		adj[w].add(v);
		E++;
		}
	}
	public Iterable<Integer> adj(int v) {
   //返回顶点的相邻顶点
		return adj[v];
	}
	public int V() {
   
		return this.V;
	}

	public int E() {
   
		return this.E;
	}
	@Override
	public String toString() {
   
		StringBuffer sb=new StringBuffer();
		sb.append("V:"+this.V+" E:"+this.E);
		for (int i = 0; i < adj.length; i++) {
   
			sb.append("\n"+i+":");
			for(int n:adj[i]){
   
				sb.append(" "+n);
			}
		}
		return sb.toString();
	}

	public static void main(String[] args) throws Exception {
   
		Graph graph=new Graph(new Scanner(new File("E:"+File.separator+"graph.txt")));
		System.out.println(graph);
	}
}

上图中Graph的输入流构造函数的输入流和toString()的结果如下所示:
在这里插入图片描述在这里插入图片描述

符号图

我们在实际使用中不会直接使用数字,而是使用名称,如第一张图中的航线图,边表示城市之间可以直达,为了使用名称完成图,实现符号图;

import java.io.*;
import java.util.*;
/**
 * 符号图:将符号和索引一一对应,图的具体实现使用索引
 * @author XY
 *
 */
public class SymbolGraph {
   
	private HashMap<String, Integer> map;//根据符号找对应索引
	private String[] index;//根据索引找符号
	private int count=0;
	private Graph graph;
	public SymbolGraph(File file,String delim) throws Exception{
   	
		map=new HashMap<String, Integer>();
//		Scanner scan=new Scanner(new BufferedInputStream(new FileInputStream(file)));
		//注意BufferedInputStream和InputStream相比缓存对IO次数的影响
		Scanner scan=new Scanner(new FileInputStream(file));
		while (scan.hasNextLine()){
   
			String[] temp=scan.nextLine().split(delim);
			for (int i = 0; i < temp.length; i++) {
   
				if(!map.containsKey(temp[i]))
				          map.put(temp[i],count++);
			}
		}
		index=new String[count];
		graph=new Graph(count);
		scan=new Scanner(file);
		while(scan.hasNextLine()){
   			
			String[] temp=scan.nextLine().split(delim);
			int v=map.get(temp[0]);
			index[v]=temp[
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值