소스 검색

Rewrites search and deepSearch to avoid recursion

Caleb Fangmeier 6 년 전
부모
커밋
2927cf64e9
1개의 변경된 파일35개의 추가작업 그리고 52개의 파일을 삭제
  1. 35 52
      src/com/pact/Node.java

+ 35 - 52
src/com/pact/Node.java

@@ -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;
     }