|
@@ -1,9 +1,6 @@
|
|
|
package com.pact;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.HashSet;
|
|
|
-import java.util.Iterator;
|
|
|
-import java.util.List;
|
|
|
+import java.util.*;
|
|
|
|
|
|
public class Node {
|
|
|
Node parent;
|
|
@@ -78,7 +75,7 @@ public class Node {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public String getVenn()
|
|
|
+ String getVenn()
|
|
|
{
|
|
|
return this.venn;
|
|
|
}
|
|
@@ -88,7 +85,7 @@ public class Node {
|
|
|
return this.venn;
|
|
|
}
|
|
|
|
|
|
- public HashSet<Node> getSiblings() {
|
|
|
+ HashSet<Node> getSiblings() {
|
|
|
if (this.parent != null) {
|
|
|
HashSet<Node> sibs = new HashSet<>(parent.children);
|
|
|
sibs.remove(this);
|
|
@@ -131,43 +128,30 @@ public class Node {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-// @Override
|
|
|
-// public int hashCode() {
|
|
|
-// if (children.isEmpty()) {
|
|
|
-// return venn.hashCode();
|
|
|
-// } else {
|
|
|
-// int h = 0;
|
|
|
-// for (Node child : children) {
|
|
|
-// h += child.hashCode();
|
|
|
-// }
|
|
|
-// return Integer.hashCode(h);
|
|
|
-// }
|
|
|
-//
|
|
|
-// }
|
|
|
+ public List<NodePair> deepSearch(Node node) {
|
|
|
+ List<NodePair> result = new ArrayList<>();
|
|
|
|
|
|
- public void _deepSearch(Node node, List<NodePair> h) {
|
|
|
- // res1: Occurrences of node in this tree
|
|
|
- List<NodePair> res1 = this.search(node);
|
|
|
+ Stack<Node> searchNodes = new Stack<>();
|
|
|
+ searchNodes.push(node);
|
|
|
+ while (!searchNodes.isEmpty()) {
|
|
|
+ Node curr = searchNodes.pop();
|
|
|
|
|
|
- // res2: Occurrences of this tree in node
|
|
|
- List<NodePair> res2 = node.search(this);
|
|
|
+ // res1: Occurrences of node in this tree
|
|
|
+ List<NodePair> res1 = this.search(curr);
|
|
|
|
|
|
- assert(res1.size() == 0 || res2.size() == 0 || res1.equals(res2));
|
|
|
+ // res2: Occurrences of this tree in node
|
|
|
+ List<NodePair> res2 = curr.search(this);
|
|
|
|
|
|
- if(!res1.isEmpty()){
|
|
|
- h.addAll(res1);
|
|
|
- } else if(!res2.isEmpty()){
|
|
|
- h.addAll(res2);
|
|
|
- }
|
|
|
+ assert(res1.size() == 0 || res2.size() == 0 || res1.equals(res2));
|
|
|
|
|
|
- for(Node child : node.children) {
|
|
|
- _deepSearch(child, h);
|
|
|
- }
|
|
|
- }
|
|
|
+ if(!res1.isEmpty()){
|
|
|
+ result.addAll(res1);
|
|
|
+ } else if(!res2.isEmpty()){
|
|
|
+ result.addAll(res2);
|
|
|
+ }
|
|
|
|
|
|
- public List<NodePair> deepSearch(Node node) {
|
|
|
- List<NodePair> result = new ArrayList<>();
|
|
|
- _deepSearch(node, result);
|
|
|
+ searchNodes.addAll(curr.children);
|
|
|
+ }
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -190,24 +174,23 @@ public class Node {
|
|
|
|
|
|
/**
|
|
|
* Search this tree for the subtree with given root
|
|
|
- * @param node the root of the subtree to search for
|
|
|
- * @param l
|
|
|
+ * @param targetNode the root of the subtree to search for
|
|
|
*/
|
|
|
- private void _search(Node node, List<NodePair> l) {
|
|
|
- if (equals(node)) {
|
|
|
- this.linkNodes.add(node);
|
|
|
- node.linkNodes.add(this);
|
|
|
- l.add(new NodePair(this, node));
|
|
|
- } else {
|
|
|
- for(Node child : children) {
|
|
|
- child._search(node, l);
|
|
|
+ private List<NodePair> search(Node targetNode) {
|
|
|
+ List<NodePair> result = new ArrayList<>();
|
|
|
+ // Use stack to avoid recursion here
|
|
|
+ Stack<Node> searchNodes = new Stack<>();
|
|
|
+ searchNodes.push(this);
|
|
|
+ while (!searchNodes.isEmpty()) {
|
|
|
+ Node curr = searchNodes.pop();
|
|
|
+ if (curr.equals(targetNode)) {
|
|
|
+ curr.linkNodes.add(targetNode);
|
|
|
+ targetNode.linkNodes.add(curr);
|
|
|
+ result.add(new NodePair(curr, targetNode));
|
|
|
+ } else {
|
|
|
+ searchNodes.addAll(curr.children);
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- private List<NodePair> search(Node node) {
|
|
|
- List<NodePair> result = new ArrayList<>();
|
|
|
- _search(node, result);
|
|
|
return result;
|
|
|
}
|
|
|
|