0

Java图实现

 2 years ago
source link: https://blog.ixk.me/post/java-graph-implementation
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Java图实现

2019-05-05 • Otstar Lin •
本文最后更新于 268 天前,文中所描述的信息可能已发生改变

没有介绍,请自行百度或谷歌,代码经过了一定的测试,但不保证没有 Bug。

1package MyGraphDemo;
2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.Collections;
6import java.util.LinkedList;
7import java.util.List;
8import java.util.Scanner;
9
10/**
11 * MyGraphDemo
12 */
13public class MyGraphDemo {
14    public static void main(String[] args) {
15        Scanner in = new Scanner(System.in);
16        MyGraph<Integer> gra = new MyGraph<Integer>();
17        gra.add(null, 0, 1);
18        gra.add(0, 1, 1);
19        gra.add(0, 2, 1);
20        gra.add(0, 3, 1);
21        gra.add(1, 2, 1);
22        gra.add(2, 3, 1);
23        gra.testString();
24        // List<MyGraph<Integer>.Vertex> list = gra.BFS(0, 3);
25        // for (MyGraph<Integer>.Vertex var : list) {
26        //     System.out.print(var.data);
27        // }
28        int[][] a = gra.toAssociationMatrix();
29        for (int i = 0; i < 4; i++) {
30            System.out.println(Arrays.toString(a[i]));
31        }
32        in.close();
33    }
34}
35
36/**
37 * MyGraph
38 * Vertex中存放顶点的信息,以及连接点列表
39 * Edge中存放权重,和与之连接点在VertexList中的索引
40 */
41class MyGraph<T extends Comparable> {
42    List<Vertex> vertexList;
43    List<EdgeNoPath> edgeList;
44    MyGraph() {
45        this.vertexList = new LinkedList<Vertex>();
46        this.edgeList = new LinkedList<EdgeNoPath>();
47    }
48    // 顶点类
49    class Vertex {
50        T data;
51        List<Edge> link;
52        Vertex() {}
53        Vertex(T data) {
54            link = new LinkedList<Edge>();
55            this.data = data;
56        }
57    }
58    // 边类
59    class Edge {
60        int prev;
61        int index;
62        int weight;
63        Edge(int index, int weight, int prev) {
64            this.prev = prev;
65            this.index = index;
66            this.weight = weight;
67        }
68    }
69    class EdgeNoPath {
70        int[] index;
71        int weight;
72        EdgeNoPath(int index1, int index2, int weight) {
73            boolean is = true;
74            for (int i = 0; i < edgeList.size(); i++) {
75                if((edgeList.get(i).index[0] == index1 && edgeList.get(i).index[1] == index2) || (edgeList.get(i).index[0] == index2 && edgeList.get(i).index[1] == index1)) {
76                    is = false;
77                    break;
78                }
79            }
80            if(is) {
81                this.weight = weight;
82                this.index = new int[2];
83                this.index[0] = index1;
84                this.index[1] = index2;
85            }
86        }
87    }
88    /**
89     * 添加顶点
90     * @param prevData  连接的上一个顶点的数据
91     * @param nextData  连接的上一个顶点的数据
92     * @param weight    边的权重
93     */
94    public void add(T prevData, T nextData, int weight) {
95        if(prevData == null && vertexList.size() == 0) {
96            vertexList.add(new Vertex(nextData));
97            return;
98        } else if(prevData == null && vertexList.size() != 0) {
99            return;
100        }
101        // 定位上一个节点
102        int prev_index = this.getIndexFromData(prevData);
103        int next_index = this.getIndexFromData(nextData);
104        Vertex new_vertex;
105        if(next_index == -1) {
106            new_vertex = new Vertex(nextData);
107            // 将新节点添加到顶点列表中
108            vertexList.add(new_vertex);
109            next_index = vertexList.size()-1;
110        } else {
111            new_vertex = vertexList.get(next_index);
112        }
113        // 将边的信息添加到新节点
114        new_vertex.link.add(new Edge(prev_index, weight, next_index));
115        // 将边的信息添加到上一个节点
116        vertexList.get(prev_index).link.add(new Edge(next_index, weight, prev_index));
117        edgeList.add(new EdgeNoPath(prev_index, next_index, weight));
118    }
119    /**
120     * 获取制定data的顶点在顶点列表中的索引
121     * @param data 要进行搜索的数据
122     * @return     返回当前数据的顶点在顶点邻接表的索引,若未找到就返回 -1
123     */
124    public int getIndexFromData(T data) {
125        int i = -1;
126        while(vertexList.size() > i+1) {
127            if(vertexList.get(i+1).data.compareTo(data) == 0) {
128                i++;
129                return i;
130            }
131            i++;
132        }
133        return -1;
134    }
135    // public int vertexOfEdge(T data) {
136
137    // }
138    public void testString() {
139        for (Vertex var : vertexList) {
140            System.out.print(var.data.toString() + ",");
141            for (Edge v : var.link) {
142                System.out.print(vertexList.get(v.index).data.toString()+" ");
143            }
144            System.out.println();
145        }
146    }
147    // 深度优先搜索 - 递归隐藏方法
148    private boolean DFS(Vertex vertex, T data, List<Vertex> list, boolean[] visited) {
149        if(vertex == null) return false;
150        if(vertex.data.compareTo(data) == 0) {
151            list.add(vertex);
152            return true;
153        }
154        for (int i = vertex.link.size()-1; i >= 0; i--) {
155            int ver_index = vertex.link.get(i).index;
156            if(!visited[ver_index]) {
157                Vertex tempVertex = vertexList.get(ver_index);
158                visited[ver_index] = true;
159                boolean is = DFS(tempVertex, data, list, visited);
160                if(is) {
161                    list.add(vertex);
162                    return true;
163                }
164                visited[ver_index] = false;
165            }
166        }
167        return false;
168    }
169    /**
170     * 深度优先搜索进行路径查找
171     * @param startData 起点
172     * @param Enddata   终点
173     * @return          返回路径的点列表
174     */
175    public List<Vertex> DFS(T startData, T endData) {
176        int start_index = this.getIndexFromData(startData);
177        boolean[] visited = new boolean[vertexList.size()];
178        visited[start_index] = true;
179        List<Vertex> list = new ArrayList<Vertex>();
180        DFS(vertexList.get(start_index), endData, list, visited);
181        Collections.reverse(list);
182        return list;
183    }
184    /**
185     * 广度优先搜索进行路径查找
186     * @param startData 起点
187     * @param Enddata   终点
188     * @return          返回路径的点列表
189     */
190    public List<Vertex> BFS(T startData, T endData) {
191        int start_index = this.getIndexFromData(startData);
192        BFS_Node endNode = null;
193        List<BFS_Node> queue = new LinkedList<BFS_Node>();
194        queue.add(new BFS_Node(vertexList.get(start_index), null));
195        while (!queue.isEmpty()) {
196            BFS_Node currentNode = queue.remove(0);
197            if(currentNode.vertex.data.compareTo(endData) == 0) {
198                endNode = currentNode;
199                break;
200            }
201            for (int i = 0; i < currentNode.vertex.link.size(); i++) {
202                queue.add(new BFS_Node(vertexList.get(currentNode.vertex.link.get(i).index), currentNode));
203            }
204        }
205        List<Vertex> list = new LinkedList<Vertex>();
206        while (endNode != null) {
207            list.add(endNode.vertex);
208            endNode = endNode.parent;
209        }
210        Collections.reverse(list);
211        return list;
212    }
213    // 广度优先搜索进行路径追踪需要的类
214    class BFS_Node {
215        Vertex vertex;
216        BFS_Node parent;
217        BFS_Node(Vertex vertex, BFS_Node parent) {
218            this.vertex = vertex;
219            this.parent = parent;
220        }
221    }
222
223    /**
224     * 将顶点列表转换为顶点数组
225     * @return 顶点数组
226     */
227    public Object[] toArraysVertex() {
228        Object[] vertexs = vertexList.toArray();
229        return vertexs;
230    }
231    /**
232     * 将邻接表的图转换为邻接矩阵
233     * @return 邻接矩阵数组
234     */
235    public int[][] toAdjacencyMatrix() {
236        int vertexSize = vertexList.size();
237        int[][] matrix = new int[vertexSize][vertexSize];
238        for (int i = 0; i < vertexSize; i++) {
239            Vertex currentVertex = vertexList.get(i);
240            for (int j = 0; j < currentVertex.link.size(); j++) {
241                Edge currentEdge = currentVertex.link.get(j);
242                matrix[i][currentEdge.index] = currentEdge.weight;
243            }
244        }
245        return matrix;
246    }
247
248    /**
249     * 将邻接表图转换为关联矩阵
250     * @return 关联矩阵数组
251     */
252    public int[][] toAssociationMatrix() {
253        int vertexSize = vertexList.size();
254        int edgeSize = edgeList.size();
255        int[][] matrix = new int[vertexSize][edgeSize];
256        for (int j = 0; j < edgeSize; j++) {
257            EdgeNoPath currentEdge = edgeList.get(j);
258            matrix[currentEdge.index[0]][j]++;
259            matrix[currentEdge.index[1]][j]++;
260        }
261        return matrix;
262    }
263}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK