java数据结构之图

图:

        一种多对多的数据结构,可以使用邻接矩阵来存储数据(邻接矩阵:假如有M个点,则创建 M * M 的邻接矩阵,【0,1】点表示0到1的点,如果其值不为0,则表示0到1的权值),如果边比较少,矩阵稀疏此方式比较浪费内存;这时候可以使用邻接表来存储数据(邻接表: 创建一个长度为M的数组a[M], 其中a[0]表示第0个节点,其值为一个链表,链表立里保存的是与第0个节点相链接的点),邻接表相对省内存,但是操作没有邻接矩阵方便。一般途中用v表示点,u表示边;图可以分为有向图和无向图,无向图——A可以到B,则默认的B可以到A,点到点之间没有方向;有向图——A可以到B,但是B不一定可以到A,点到点之间是有方向的。加权图——点到点之间的距离不一样,它们之间不同的距离用不同的权来表示,还可以称为网。

图的广度优先遍历与深度优先遍历:

public class MapDemo {
    private ArrayList<String> vertexList; //存储顶点集合
    private int[][] edges; //
    private int numOfedges; //表示边的数目
    //定义一个数组用来记录某个顶点是否被访问过
    private boolean[] isVisited;

    public static void main(String[] args) {
        //测试
        int n = 8;
//        String VertexVal[] = {"A", "B","C","D","E"} ;
        String VertexVal[] = {"1", "2","3","4","5","6","7","8"} ;
        //创建图对象
        MapDemo mapDemo = new MapDemo(n);
        for (String val : VertexVal) {
            mapDemo.insertVertex(val);
        }
        //添加边
        mapDemo.insertEdge(0,1,1);
        mapDemo.insertEdge(0,2,1);
        mapDemo.insertEdge(1,3,1);
        mapDemo.insertEdge(1,4,1);
        mapDemo.insertEdge(3,7,1);
        mapDemo.insertEdge(4,7,1);
        mapDemo.insertEdge(2,5,1);
        mapDemo.insertEdge(2,6,1);
        mapDemo.insertEdge(5,6,1);
        mapDemo.showMap();

        System.out.println("深度优先遍历");
        mapDemo.dfs();

//        mapDemo.bfs();
    }

    //构造器
    public MapDemo(int n) {
        //初始化矩阵和vertexList
        edges = new int[n][n];
        vertexList = new ArrayList<>(n);
        numOfedges = 0;
        isVisited = new boolean[n];
    }

    //得到第一个邻接节点的下标w
    public int getFirstNeighbor(int index) {
        for (int j = 0; j < vertexList.size(); j++) {
            if (edges[index][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    //根据前一个邻接节点的下标,获取下一个邻接节点
    public int getNextNeighbor(int v1, int v2) {
        for (int j = v2+1; j < vertexList.size(); j++) {
            if (edges[v1][j] > 0) {
                return j;
            }
        }

        return -1;
    }

    //深度优先遍历
    public void dfs(boolean[] isVisited, int i) {
        //访问该节点
        System.out.print(getValueByIndex(i) + "->");
        isVisited[i] = true;

        int w = getFirstNeighbor(i);
        while (w != -1) {
            if (!isVisited[w]) {
                dfs(isVisited, w);
            }
            w = getNextNeighbor(i, w);
        }

    }
    //
    public void dfs() {
        //遍历所有的节点
        for (int i = 0; i < getNumOfVertex(); i++) {
            if (!isVisited[i] ) {
                dfs(isVisited, i);
            }
        }
    }

    //广度优先算法
    private void bfs() {
        int u; //表示队列的头结点对应的下标
        int w; //邻接节点w
        int i = 0;
        //队列
        LinkedList<Integer> queue = new LinkedList<>();
        queue.addLast(i);
        isVisited[i] = true;
        while (!queue.isEmpty()) {
            //取出队列的头
            Integer integer = queue.removeFirst();
            u = integer;
            w = getFirstNeighbor(u);
            while (w != -1) {
                if (!isVisited[w]) {
                    isVisited[w] = true;
                    queue.addLast(w);
                }
                w = getNextNeighbor(u, w);
            }

            System.out.print(getValueByIndex(u) + "=>");
        }

    }

    //返回节点的个数
    public int getNumOfVertex() {
        return vertexList.size();
    }

    //得到边的数目
    public int getNumOfedges() {
        return numOfedges;
    }
    //返回i下标对应的数据: 0 -> A, 1 -> B, 2->C
    public String getValueByIndex(int i) {
        return vertexList.get(i);
    }

    //返回v1和v2的权值
    public int getWeight(int v1, int v2) {
        return edges[v1][v2];
    }

    //插入节点
    public void insertVertex(String vertex) {
        vertexList.add(vertex);
    }

    //显示图对应的矩阵
    public void showMap() {
        for (int i = 0; i < edges.length; i++) {
            System.err.println(Arrays.toString(edges[i]));
        }
    }

    //添加边
    /**
     *
     * @param v1 表示点的下标,即第几个顶点
     * @param v2 表示点的下标,
     * @param weight 路径上的权值
     */
    public void insertEdge(int v1, int v2, int weight) {
        edges[v1][v2] = weight;
        edges[v2][v1] = weight;
        numOfedges++;
    }

}

 

发布了52 篇原创文章 · 获赞 4 · 访问量 9334
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章