zoukankan      html  css  js  c++  java
  • 图建模

      为了方便的使用图这个数据结构,我们需要使用编程语言对其抽象的内容进行具体化,我们在设计一个复杂的数据结构的时候可以参考Java集合框架的特点,首先定义一个接口,包含的是图的所有的常用的公共的操作,然后定义一个抽象类来部分地实现这个接口,最后根据具体的使用情况定义具体的类实现抽象类。

      图的常用操作:

        1、获取图中顶点个数

        2、获取图中的顶点

        3、返回指定顶点下标的顶点对象

        4、返回指定顶点的下标

        5、返回指定下标的顶点的邻居

        6、打印边

        7、清除图

        8、添加顶点

        9、添加边

    通过接口,将这些图的常用操作定义封装在一起:

    import java.util.List;
    
    /**
     *
     * @param <V> 参数V是一个泛型,表示图中顶点
     *
     */
    public interface Graph<V> {
        /**
         *
         * @return 返回值是图中的顶点个数
         */
        public int getSize();
    
        /**
         *
         * @return 返回值是图中所有的顶点对象
         */
        public List<V> getVertices();
    
        /**
         *
         * @param index 表示要获取的顶点的索引
         * @return 返回指定下标的顶点对象
         */
        public V getVertex(int index);
    
        /**
         *
         * @param v 参数v表示要获取下标的顶点对象
         * @return 返回值是指定下标的顶点的索引
         */
    
        public int getIndex(V v);
    
        /**
         *
         * @param index
         * @return  返回指定下标的顶点的邻居
         */
    
        public List<Integer> getNeighbors(int index);
    
        /**
         *
         * @param v
         * @return  返回指定顶点的度
         */
        public int getDegree(int v);
    
        /**
         * 打印所有的边
         */
    
        public void printEdges();
    
        /**
         * 清楚图
         */
        public void clear();
    
        /**
         * 向图中添加顶点vertex
         * @param vertex
         */
        public boolean addVertex(V vertex);
    
        /**
         * 向图中添加边<u,v>
         * @param u
         * @param v
         */
        public boolean addEdge(int u,int v);
    }

      定义一个抽象类,部分实现了上面的接口,其实已经实现了接口中所有的方法,但是为了以后方便的在接口中增加新的方法,而这个方法不需要当前这个抽象类来实现,所以将这个类定义为抽象类,方便维护接口和类。

    import java.util.ArrayList;
    import java.util.List;
    
    public abstract class AbstractGraph<V> implements Graph<V> {
    
        List<V> vertices = new ArrayList<>();
        List<List<Edge>> neighbors = new ArrayList<>();
    
        public AbstractGraph() {
        }
    
        /**
         * 由一个顶点数组和边数组构建一个图
         * @param vertices
         * @param edges
         */
        public AbstractGraph(V[] vertices,int[][] edges ) {
    
            for (V vertex : vertices) {
                addVertex(vertex);
            }
            createAdjacencyLists(edges);
        }
    
        protected  void createAdjacencyLists(int[][] edges){
    
            for (int i = 0; i < edges.length; i++) {
    
                addEdge(edges[i][0],edges[i][1]);
            }
        }
    
        /**
         * 由一个顶点列表和一个边列表构建图
         * @param edges
         */
        public AbstractGraph(List<V> vertices,List<Edge> edges) {
    
            for (V vertex : vertices) {
                addVertex(vertex);
            }
            createAdjacencyLists(edges);
        }
    
        protected  void createAdjacencyLists(List<Edge> edges){
    
            for (Edge edge : edges) {
                addEdge(edge.getU(),edge.getV());
            }
        }
    
        @Override
        public int getSize() {
            return vertices.size();
        }
    
        @Override
        public List getVertices() {
            return vertices;
        }
    
        @Override
        public V getVertex(int index) {
            return vertices.get(index);
        }
    
        @Override
        public int getIndex(V v) {
            return vertices.indexOf(v);
        }
    
        @Override
        public List<Integer> getNeighbors(int index) {
    
            ArrayList<Integer> res = new ArrayList<>();
    
            for (Edge edge : neighbors.get(index)) {
                res.add(edge.getV());
            }
            return res;
        }
    
        @Override
        public int getDegree(int v) {
            return neighbors.get(v).size();
        }
    
        @Override
        public void printEdges() {
    
            for (int i = 0; i < neighbors.size(); i++) {
    
                System.out.println(getVertex(i) + "(" + i + "):" );
                for (Edge edge : neighbors.get(i)) {
                    System.out.println("(" + getVertex(edge.getU()) + "," + getVertex(edge.getV()) + ")");
                }
                System.out.println();
            }
        }
    
        @Override
        public void clear() {
            vertices.clear();
            neighbors.clear();
        }
    
        @Override
        public boolean addVertex(V vertex) {
            
            if (!vertices.contains(vertex)){
                vertices.add(vertex);
                neighbors.add(new ArrayList<Edge>());
                return true;
            }
            return false;
        }
    
        @Override
        public boolean addEdge(int u, int v) {
            
            return addEdge(new Edge(u,v));
        }
    
        private boolean addEdge(Edge edge) {
            
            if (!neighbors.get(edge.getU()).contains(edge)){
                
                neighbors.get(edge.getU()).add(edge);
            }
            return false;
        }
    }

    需要注意的是,上面的那个变量neighbors表示的就是邻接边线性表,这个线性表的每一个元素都是一个列表类型,而这个列表中的元素类型都是Edge对象类型,即存储的都是一个个边对象。它们数据结构如下图所示:

     neighbors[i]是表示包含顶点i的所有邻接边列表,这里边的都是以i作为出发点的,<i,x>

  • 相关阅读:
    bzoj 1800 & 洛谷 P2165 [AHOI2009]飞行棋 —— 模拟
    bzoj 1050 [ HAOI 2006 ] 旅行comf —— 并查集
    洛谷P2593 [ ZJOI 2006 ] 超级麻将 —— DP
    bzoj 3029 守卫者的挑战 —— 概率DP
    poj 2288 Islands and Bridges ——状压DP
    bzoj 1029 [ JSOI 2007 ] 建筑抢修 —— 贪心
    bzoj 3743 [ Coci 2015 ] Kamp —— 树形DP
    bzoj 1053 [ HAOI 2007 ] 反素数ant ——暴搜
    【构造共轭函数+矩阵快速幂】HDU 4565 So Easy! (2013 长沙赛区邀请赛)
    构造类斐波那契数列矩阵(矩阵
  • 原文地址:https://www.cnblogs.com/yxym2016/p/13122054.html
Copyright © 2011-2022 走看看