无向图的创建(java实现)

一、无向图的几种数据结构

我们要面对的下一个图处理问题就是用哪种方式(数据结构)来表示图并实现这份 API,这包含以下两个要求:

  • 它必须为可能在应用中碰到的各种类型图预留足够的空间;
  • 实现一定要块 
     
  1. 邻接矩阵:我们可以使用V乘V的布尔矩阵。当顶点v和顶点w之间有相连接边时,定义v 行w列的元素为true,否则为false。当含有上百万个顶点的图是很常见的,V^2个布尔值所需的空间是不能满足的。其次大部分图都是稀疏的,所以用邻接矩阵表示浪费空间。
  2. 邻接表:我们可以使用一个以顶点为索引的列表数组,其中的每个元素都是和该顶点相邻的顶点列表。这种数据结构能够同时满足以上的两个条件,所以我准备用java实现这种结构。

二、api定义

Graph
public Graph()
无参构造函数
public Graph(int vertices)
有参构造函数,vertices为顶点数
public void createGraphByFile(String path)
根据文件创建图,path为文件路径
public void addEdge(int v,int w)
添加一条边,v和w是顶点编号
public Collection<Integer> adj(int v)
返回与v相邻的所有顶点列表
public int getVertices()
返回顶点数
public int getEdges()
返回边数
public String toString()
打印邻接表

 

三、代码实现

package graph;

import java.io.*;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
 * 使用邻接表实现图算法
 * @author hh
 */
public class Graph {
    /**
     * 顶点数
     */
    private int vertices;

    /**
     * 边数
     */
    private int edges;

    /**
     * 邻接表
     */
    private List<Integer>[] adj;

    public Graph() {
    }

    public Graph(int vertices) {
        this.init(vertices);
    }

    /**
     * 从文件中创建图
     * @param path :文件路径
     */
    public  void createGraphByFile(String path) throws Exception{
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(path)))) {
            int vs = Integer.parseInt(bufferedReader.readLine().trim());
            int es = Integer.parseInt(bufferedReader.readLine().trim());
            if(vs <= 0){
                throw new  IllegalArgumentException("顶点数量必须大于0!");
            }
            if(es < 0){
                throw new  IllegalArgumentException("边的数量必须大于等于0!");
            }
            init(vs);
            for(int i = 0 ; i < es ; i++){
                String[] vl =  bufferedReader.readLine().trim().split(" ");
                this.addEdge(Integer.parseInt(vl[0].trim()),Integer.parseInt(vl[1].trim()));
            }

        } catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 添加一条边
     * @param v :顶点v编号
     * @param w :顶点w编号
     */
    public void addEdge(int v,int w){
        this.adj[v].add(w);
        this.adj[w].add(v);
        this.edges++;
    }

    /**
     * 返回与v相邻的所有顶点列表
     * @param v :顶点编号
     * @return :返回与v相邻的所有顶点列表
     */
    public Collection<Integer> adj(int v){
        return  adj[v];
    }

    /**
     * @return :返回顶点数
     */
    public int getVertices() {
        return vertices;
    }

    /**
     * @return ;返回边数
     */
    public int getEdges() {
        return edges;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder(this.edges*this.vertices);
        for(int i=0 ; i < this.vertices ;i++){
            stringBuilder.append(i).append("->").append(adj[i]).append("\n");
        }
        return stringBuilder.toString();
    }

    private void init(int vertices){
        this.vertices = vertices;
        //初始化邻接表
        this.adj = new LinkedList[vertices];
        for(int i = 0;i < vertices; i++){
            this.adj[i] = new LinkedList<>();
        }
    }
}

测试从文件创建图,文件定义格式如下:

测试代码如下:

public class GraphTest {

    public static void main(String[] args) throws Exception {
        String filename = "D:\\Desktop\\graph.txt";
        Graph graph = new Graph();
        graph.createGraphByFile(filename);
        System.out.println(graph);
        
    }
}

执行结果如下:

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值