Find the next larger node in the generic tree?
我必须找到并返回通用树中的下一个更大的节点,几乎所有的测试用例都运行正常并给出正确的输出,只有一个测试用例出错了,它可能是任何东西。 我已多次调试我的程序,无法弄清楚可能出现的错误是什么? 实际上我在做什么我正在比较递归为我提取的所有下一个更大的节点并将它们相互比较并最终找到正确的节点? 我被困了一点帮助将不胜感激。
码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /* TreeNode structure class TreeNode< T > { T data; ArrayList<TreeNode< T >> children; TreeNode(T data){ this.data = data; children = new ArrayList<TreeNode< T >>(); } }*/ public static TreeNode<Integer> findNextLargerNode(TreeNode<Integer> root, int n){ if(root==null) return root; if(root.children.size()==0) { if(root.data>n) { return root; } else return null; } TreeNode<Integer> count[] = new TreeNode[root.children.size()]; for(int i=0;i<root.children.size();i++) { count[i] = findNextLargerNode(root.children.get(i),n); } int nextLarger=Integer.MAX_VALUE; TreeNode<Integer> next = null; for(int i=0;i<count.length;i++) { if(count[i]!=null) { if(count[i].data>n && count[i].data<nextLarger) { nextLarger = count[i].data; next = count[i]; } } } if(next!=null) { if(root.data>n && root.data<next.data) return root; else return next; } else return null; } |
尝试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class Test { class TreeNode< T > { T data; List<TreeNode< T >> children; TreeNode(T data) { this.data = data; children = new ArrayList<TreeNode< T >>(); } public TreeNode< T > findNextNode(T n,Comparator< T > comp) { if (comp.compare(data , n) < 0) { return this; } if (children.size() == 0) { return null; } for (int i = 0; i < children.size(); i++) { TreeNode< T > node= children.get(i).findNextNode(n,comp); if(node!=null)return node; } return null; } } |
说明:
测试
为了在代码中显示一些错误,我在
在
通用
而不是编写只能处理
对照
实际比较被委托给Comparator对象。必须将Comparator的实例传递给findNextNode方法。这可以使用Java 8 lambda语法即时完成,例如
它能做什么
如果入口节点满足Comparator.compare实现定义的条件,则算法将停止。否则,从第一个子节点开始执行深度搜索(等等)。一旦节点与比较标准匹配,算法就会停止。如果没有节点匹配,则返回null。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | package stack43210199; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import org.junit.Assert; public class Test { class TreeNode< T > { T data; List<TreeNode< T >> children; TreeNode(T data) { this.data = data; children = new ArrayList<TreeNode< T >>(); } public TreeNode< T > findNextNode(T n,Comparator< T > comp) { if (comp.compare(data , n) < 0) { return this; } if (children.size() == 0) { return null; } for (int i = 0; i < children.size(); i++) { TreeNode< T > node= children.get(i).findNextNode(n,comp); if(node!=null)return node; } return null; } } @org.junit.Test public void testForYourCode() { TreeNode<Integer> root = buildNode(0); TreeNode<Integer> firstChild = buildNode(5); TreeNode<Integer> secondChild = buildNode(4); TreeNode<Integer> thirdChild = buildNode(5); root.children.add(firstChild); root.children.add(secondChild); root.children.add(thirdChild); //Arrg - not as expected Assert.assertEquals(secondChild, findNextLargerNode(root, 0)); } @org.junit.Test public void testForModifiedCode() { TreeNode<Integer> root = buildNode(2); TreeNode<Integer> firstChild = buildNode(5); TreeNode<Integer> secondChild = buildNode(4); TreeNode<Integer> thirdChild = buildNode(5); TreeNode<Integer> fourthChild = buildNode(1); root.children.add(firstChild); root.children.add(secondChild); root.children.add(thirdChild); thirdChild.children.add(fourthChild); //find next greater Assert.assertEquals(firstChild, root.findNextNode(2,(a,b)->{return b-a;})); //find next lesser Assert.assertEquals(fourthChild, root.findNextNode(2,(a,b)->{return a-b;})); } @org.junit.Test public void testForModifiedCodeComplex() { TreeNode<Integer> root = buildNode(2); TreeNode<Integer> firstChild = buildNode(2); TreeNode<Integer> secondChild = buildNode(4); TreeNode<Integer> thirdChild = buildNode(5); TreeNode<Integer> fourthChild = buildNode(1); TreeNode<Integer> sixthChild = buildNode(8); firstChild.children.add(fourthChild); firstChild.children.add(sixthChild); root.children.add(firstChild); root.children.add(secondChild); root.children.add(thirdChild); //find next greater Assert.assertEquals(sixthChild, root.findNextNode(2,(a,b)->{return b-a;})); //find next lesser Assert.assertEquals(fourthChild, root.findNextNode(2,(a,b)->{return a-b;})); } private TreeNode<Integer> buildNode(int i) { return new TreeNode<Integer>(new Integer(i)); } public static TreeNode<Integer> findNextLargerNode(TreeNode<Integer> root, int n) { if (root == null) return root; if (root.children.size() == 0) { if (root.data > n) { return root; } else return null; } TreeNode<Integer> count[] = new TreeNode[root.children.size()]; for (int i = 0; i < root.children.size(); i++) { count[i] = findNextLargerNode(root.children.get(i), n); } int nextLarger = Integer.MAX_VALUE; TreeNode<Integer> next = null; for (int i = 0; i < count.length; i++) { if (count[i] != null) { if (count[i].data > n && count[i].data < nextLarger) { nextLarger = count[i].data; next = count[i]; } } } if (next != null) { if (root.data > n && root.data < next.data) return root; else return next; } else { if (root.data > n) return root; else return null; } } } |
最后,我在代码中发现了这个错误。它位于以下部分。
1 2 3 4 5 6 7 8 9 10 | if(next!=null) { if(root.data>n && root.data<next.data) return root; else return next; } else return null; |
假设如果
正确的版本是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | if(next!=null) { if(root.data>n && root.data<next.data) return root; else return next; } else { if(root.data>n) return root; else return null; } |
我看到一个极端测试可能会失败:如果正确答案是一个具有数据
对代码进行最少更改的解决方案是替换:
1 | count[i].data<nextLarger |
有:
1 | count[i].data<=nextLarger |
这样,即使
注意:如果要将两个
TreeNode通常看起来像这样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class TreeNode<T extends Comparable< T >> { T data; TreeNode< T > left, right; TreeNode(T data){ this.data = data; } public TreeNode< T > findNextLargerNode(T t) { if (data.compareTo(t) <= 0) return right == null ? null : right.findNextLargerNode(t); T found = left == null ? null : left.findNextLargerNode(t); return found == null ? this : found; } } |