[英]Find loop in Tree preferred in java
我在数据库项目文件夹层次结构中有一组数据(如快照)
我在数据中有一个循环
像 A->B , B->C C->D , C->A
代码如下:
public class Vertex {
private String label;
private boolean beingVisited;
private boolean visited;
private List<Vertex> adjacencyList;
public Vertex(String label) {
this.label = label;
this.adjacencyList = new ArrayList<>();
}
public void addNeighbor(Vertex adjacent) {
this.adjacencyList.add(adjacent);
}
//getters and setters
}
public class Graph {
private List<Vertex> vertices;
public Graph() {
this.vertices = new ArrayList<>();
}
public void addVertex(Vertex vertex) {
if(!vertices.contains(vertex)){
this.vertices.add(vertex);
}
}
public void addEdge(Vertex from, Vertex to) {
from.addNeighbor(to);
}
// ...
public boolean hasCycle(Vertex sourceVertex) {
sourceVertex.setBeingVisited(true);
for (Vertex neighbor : sourceVertex.getAdjacencyList()) {
if (neighbor.isBeingVisited()) {
// backward edge exists
return true;
} else if (!neighbor.isVisited() && hasCycle(neighbor)) {
return true;
}
}
sourceVertex.setBeingVisited(false);
sourceVertex.setVisited(true);
return false;
}
public boolean hasCycle() {
for (Vertex vertex : vertices) {
if (!vertex.isVisited() && hasCycle(vertex)) {
return true;
}
}
return false;
}
//主要的
public static void main(String[] args) {
Graph graph = new Graph();
ResultSet rs = provider.conn.createStatement().executeQuery("SELECT itemId, folder FROM SnapshotData);
while (rs.next()) {
Vertex vertexFrom = new Vertex(rs.getString("itemId"));
Vertex vertexTo = new Vertex(rs.getString("folder"));
graph.addVertex(vertexFrom);
graph.addVertex(vertexTo);
graph.addEdge(vertexFrom, vertexTo);
}
assertTrue(graph.hasCycle());
}
我被我错过的东西困住了
据我所知,您的问题是创建节点。
while (rs.next()) {
Vertex vertexFrom = new Vertex(rs.getString("itemId"));
Vertex vertexTo = new Vertex(rs.getString("folder"));
graph.addEdge(vertexFrom, vertexTo);
}
如果我们截取您的屏幕截图,您有 5 个元素(A、B、C、D、F),但您正在创建 10 个(2xA、2xB、4xC、1xF。因此没有循环,因为您的图形如下所示:
A---B
B---C
C---D
C---A
C---F
我建议将您创建的节点保存在 set/HashMap 中,如果它们已经存在,则从那里获取它,而不是创建新的节点。 像这样的东西(没有测试):
Map<String,Vertex> verticesList = new HashMap<String,Vertex>();
while (rs.next()) {
String from = rs.getString("itemId");
Vertex vertexFrom = null;
if(verticesList.contains(from)){
vertexFrom = verticesList.get(from);
} else {
vertexFrom = new Vertex(from);
verticesList.put(from,vertexFrom);
}
... //same for the other vertex
graph.addEdge(vertexFrom, vertexTo);
}
@Edit:一个可运行的例子:
图形:
public class Graph {
private List<Vertex> vertices;
public Graph() {
this.vertices = new ArrayList<>();
}
public void addVertex(Vertex vertex) {
if (!vertices.contains(vertex)) {
this.vertices.add(vertex);
}
}
public void addEdge(Vertex from, Vertex to) {
from.addNeighbor(to);
}
public boolean hasCycle(Vertex sourceVertex) {
sourceVertex.setBeingVisited(true);
for (Vertex neighbor : sourceVertex.getAdjacencyList()) {
if (neighbor.isBeingVisited()) {
// backward edge exists
return true;
} else if (!neighbor.isVisited() && hasCycle(neighbor)) {
return true;
}
}
sourceVertex.setBeingVisited(false);
sourceVertex.setVisited(true);
return false;
}
public boolean hasCycle() {
for (Vertex vertex : vertices) {
if (!vertex.isVisited() && hasCycle(vertex)) {
return true;
}
}
return false;
}
}
顶点:
public class Vertex {
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
private String label;
public boolean isBeingVisited() {
return beingVisited;
}
public void setBeingVisited(boolean beingVisited) {
this.beingVisited = beingVisited;
}
public boolean isVisited() {
return visited;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
private boolean beingVisited;
public List<Vertex> getAdjacencyList() {
return adjacencyList;
}
public void setAdjacencyList(List<Vertex> adjacencyList) {
this.adjacencyList = adjacencyList;
}
private boolean visited;
private List<Vertex> adjacencyList;
public Vertex(String label) {
this.label = label;
this.adjacencyList = new ArrayList<>();
}
public void addNeighbor(Vertex adjacent) {
this.adjacencyList.add(adjacent);
}
}
主要的:
public class Main {
public static void main(String[] args) {
Graph graph = new Graph();
String[][] rs = new String[5][2];
rs[0][0] = "A";
rs[0][1] = "B";
rs[1][0] = "B";
rs[1][1] = "C";
rs[2][0] = "C";
rs[2][1] = "D";
rs[3][0] = "C";
rs[3][1] = "A";
rs[4][0] = "C";
rs[4][1] = "F";
HashMap<String,Vertex> verticesList = new HashMap<String,Vertex>();
for(int i = 0; i<rs.length;i++){
String from = rs[i][0];
String to = rs[i][1];
System.out.println("From: " + from + " to: " + to);
Vertex vertexFrom;
Vertex vertexTo;
if (verticesList.containsKey(from)) {
vertexFrom = verticesList.get(from);
} else {
vertexFrom = new Vertex(from);
verticesList.put(from,vertexFrom);
}
if (verticesList.containsKey(to)) {
vertexTo = verticesList.get(to);
} else {
vertexTo = new Vertex(to);
verticesList.put(to,vertexTo);
}
graph.addVertex(vertexTo);
graph.addVertex(vertexFrom);
graph.addEdge(vertexFrom, vertexTo);
}
System.out.println(graph.hasCycle());
System.out.println(verticesList.size());
}
}
输出:
From: A to: B
From: B to: C
From: C to: D
From: C to: A
From: C to: F
true
5
这样你就永远找不到循环 ab, bc, ac。
如果要检查算法,请手动计算其中间结果并检查它们 - 所有这些,而不仅仅是最后一个。 这是你的工作,不是我们的。
把所有合适的代码放在这里。 如我所见,您的示例问题不在hasCycle
方法中。 我会检查吸气剂/二传手。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.