比较两组二叉树
compare two sets of binarytrees
我应该创建一个 equals() 方法来比较两棵树。 无论第二棵树的顺序如何,如果它包含第一棵树的所有元素,它应该return为真。
我已经制作了一个 equals() 方法,如果两棵树相同,该方法将 return 为真,请参阅下面的代码。
我的方法是,通过递归,向上遍历第二棵树并将其与第一棵树的一个节点进行比较。如果我得到一个匹配项,我会 return true 并继续我的第一棵树中的另一个节点。如果我在没有匹配的情况下通过第二棵树,我会 return false.
我比较两棵树是否相等的代码:
public boolean equals(BST t) {
return equalsTree(root, t.root);
}
public boolean equalsTree(Node r, Node t){
if(r == null && t == null){
return true;
}else if((r != null && t == null) || (r==null && t != null)){
return false;
}else{
return t.key.equals(r.key) && (equalsTree(r.left,t.left)) && (equalsTree(r.right, t.right));
}
}
你的想法是对的。您需要比较左右分支是否匹配。如果他们不比较对立面的话。
| 1 | { | { |
| 2 | v: 0 | v: 0 |
| 3 | l: { | l: { |
| 4 | v: 1, | v: 2 |
| 5 | l: null | l: null |
| 6 | r: null | r : { |
| 7 | }, | v: 3 |
| 8 | r: { | l: null |
| 9 | v: 2 | r: null |
| 10 | l: { | } |
| 11 | v: 3 | } |
| 12 | l: null | r: { |
| 13 | r: null | v: 1 |
| 14 | }, | l: null |
| 15 | r: null | r: null |
| 16 | } | } |
| 17 | } | } |
正如您在上面看到的,两个根节点的值为零,但它们相对的分支具有相同的节点。第一棵树的右节点 (2) 有一个值为 (3) 的左节点。第二棵树的左节点 (2) 也有一个值为 (3) 的子节点,但它是正确的。由于顺序无关紧要,因此两棵树都是相等的。
TreeCompare.java
public class TreeCompare {
public static void main(String[] args) {
Tree<Integer> treeA = new Tree<Integer>();
Tree<Integer> treeB = new Tree<Integer>();
Node<Integer> treeArootNode = new Node<Integer>(0);
Node<Integer> treeBrootNode = new Node<Integer>(0);
Node<Integer> treeAnode1 = new Node<Integer>(1);
Node<Integer> treeAnode2 = new Node<Integer>(2);
Node<Integer> treeAnode3 = new Node<Integer>(3);
Node<Integer> treeBnode1 = new Node<Integer>(1);
Node<Integer> treeBnode2 = new Node<Integer>(2);
Node<Integer> treeBnode3 = new Node<Integer>(3);
treeA.root = treeArootNode;
treeB.root = treeBrootNode;
treeA.root.left = treeAnode1;
treeA.root.right = treeAnode2;
treeB.root.left = treeBnode2;
treeB.root.right = treeBnode1;
treeAnode2.left = treeAnode3;
treeBnode2.right = treeBnode3; // or treeBnode2.left
System.out.println(treeA);
System.out.println(treeB);
System.out.println(treeA.equals(treeB));
}
}
Tree.java
public class Tree<T> {
public Node<T> root;
@SuppressWarnings("unchecked")
public boolean equals(Object other) {
Tree<T> otherTree = (Tree<T>) other;
if (other == null) return false;
if (this.root == null && otherTree.root != null) return false;
if (this.root != null && otherTree.root == null) return false;
return equalsNode(this.root, otherTree.root);
}
public boolean equalsNode(Node<T> nodeA, Node<T> nodeB) {
if (nodeA == null && nodeB == null) return true;
if (nodeA == null && nodeB != null) return false;
if (nodeA != null && nodeB == null) return false;
if (nodeA.equals(nodeB)) {
if (nodeA.value == null && nodeB.value != null) return false;
if (nodeA.value != null && nodeB.value == null) return false;
if (nodesEqualSameLeft(nodeA, nodeB) && nodesEqualSameRight(nodeA, nodeB)) {
return equalsNode(nodeA.left, nodeB.left) && equalsNode(nodeA.right, nodeB.right);
}
if (nodesEqualOppositeLeft(nodeA, nodeB) && nodesEqualOppositeRight(nodeA, nodeB)) {
return equalsNode(nodeA.left, nodeB.right) && equalsNode(nodeA.right, nodeB.left);
}
}
return false;
}
public boolean nodesEqualSameLeft(Node<T> nodeA, Node<T> nodeB) {
return nodesEqual(nodeA.left, nodeB.left);
}
public boolean nodesEqualSameRight(Node<T> nodeA, Node<T> nodeB) {
return nodesEqual(nodeA.right, nodeB.right);
}
public boolean nodesEqualOppositeLeft(Node<T> nodeA, Node<T> nodeB) {
return nodesEqual(nodeA.left, nodeB.right);
}
public boolean nodesEqualOppositeRight(Node<T> nodeA, Node<T> nodeB) {
return nodesEqual(nodeA.right, nodeB.left);
}
public boolean nodesEqual(Node<T> nodeA, Node<T> nodeB) {
return (nodeA == null && nodeB == null) || (nodeA != null && nodeA.equals(nodeB));
}
@Override
public String toString() {
return root.toString();
}
}
Node.java
public class Node<T> {
public Node<T> left;
public Node<T> right;
public T value;
public Node(Node<T> left, Node<T> right, T value) {
this.left = left;
this.right = right;
this.value = value;
}
public Node(T value) {
this(null, null, value);
}
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object other) {
Node<T> otherNode = (Node<T>) other;
if (other == null) return false;
if (this.value == null && otherNode.value != null) return false;
if (this.value != null && otherNode.value == null) return false;
return this.value.equals(otherNode.value);
}
@Override
public String toString() {
return String.format("{ \"v\" : %s, \"l\" : %s, \"r\" : %s }", value, left, right);
}
}
输出
{ "v" : 0, "l" : { "v" : 1, "l" : null, "r" : null }, "r" : { "v" : 2, "l" : { "v" : 3, "l" : null, "r" : null }, "r" : null } }
{ "v" : 0, "l" : { "v" : 2, "l" : null, "r" : { "v" : 3, "l" : null, "r" : null } }, "r" : { "v" : 1, "l" : null, "r" : null } }
true
我应该创建一个 equals() 方法来比较两棵树。 无论第二棵树的顺序如何,如果它包含第一棵树的所有元素,它应该return为真。
我已经制作了一个 equals() 方法,如果两棵树相同,该方法将 return 为真,请参阅下面的代码。 我的方法是,通过递归,向上遍历第二棵树并将其与第一棵树的一个节点进行比较。如果我得到一个匹配项,我会 return true 并继续我的第一棵树中的另一个节点。如果我在没有匹配的情况下通过第二棵树,我会 return false.
我比较两棵树是否相等的代码:
public boolean equals(BST t) {
return equalsTree(root, t.root);
}
public boolean equalsTree(Node r, Node t){
if(r == null && t == null){
return true;
}else if((r != null && t == null) || (r==null && t != null)){
return false;
}else{
return t.key.equals(r.key) && (equalsTree(r.left,t.left)) && (equalsTree(r.right, t.right));
}
}
你的想法是对的。您需要比较左右分支是否匹配。如果他们不比较对立面的话。
| 1 | { | { |
| 2 | v: 0 | v: 0 |
| 3 | l: { | l: { |
| 4 | v: 1, | v: 2 |
| 5 | l: null | l: null |
| 6 | r: null | r : { |
| 7 | }, | v: 3 |
| 8 | r: { | l: null |
| 9 | v: 2 | r: null |
| 10 | l: { | } |
| 11 | v: 3 | } |
| 12 | l: null | r: { |
| 13 | r: null | v: 1 |
| 14 | }, | l: null |
| 15 | r: null | r: null |
| 16 | } | } |
| 17 | } | } |
正如您在上面看到的,两个根节点的值为零,但它们相对的分支具有相同的节点。第一棵树的右节点 (2) 有一个值为 (3) 的左节点。第二棵树的左节点 (2) 也有一个值为 (3) 的子节点,但它是正确的。由于顺序无关紧要,因此两棵树都是相等的。
TreeCompare.java
public class TreeCompare {
public static void main(String[] args) {
Tree<Integer> treeA = new Tree<Integer>();
Tree<Integer> treeB = new Tree<Integer>();
Node<Integer> treeArootNode = new Node<Integer>(0);
Node<Integer> treeBrootNode = new Node<Integer>(0);
Node<Integer> treeAnode1 = new Node<Integer>(1);
Node<Integer> treeAnode2 = new Node<Integer>(2);
Node<Integer> treeAnode3 = new Node<Integer>(3);
Node<Integer> treeBnode1 = new Node<Integer>(1);
Node<Integer> treeBnode2 = new Node<Integer>(2);
Node<Integer> treeBnode3 = new Node<Integer>(3);
treeA.root = treeArootNode;
treeB.root = treeBrootNode;
treeA.root.left = treeAnode1;
treeA.root.right = treeAnode2;
treeB.root.left = treeBnode2;
treeB.root.right = treeBnode1;
treeAnode2.left = treeAnode3;
treeBnode2.right = treeBnode3; // or treeBnode2.left
System.out.println(treeA);
System.out.println(treeB);
System.out.println(treeA.equals(treeB));
}
}
Tree.java
public class Tree<T> {
public Node<T> root;
@SuppressWarnings("unchecked")
public boolean equals(Object other) {
Tree<T> otherTree = (Tree<T>) other;
if (other == null) return false;
if (this.root == null && otherTree.root != null) return false;
if (this.root != null && otherTree.root == null) return false;
return equalsNode(this.root, otherTree.root);
}
public boolean equalsNode(Node<T> nodeA, Node<T> nodeB) {
if (nodeA == null && nodeB == null) return true;
if (nodeA == null && nodeB != null) return false;
if (nodeA != null && nodeB == null) return false;
if (nodeA.equals(nodeB)) {
if (nodeA.value == null && nodeB.value != null) return false;
if (nodeA.value != null && nodeB.value == null) return false;
if (nodesEqualSameLeft(nodeA, nodeB) && nodesEqualSameRight(nodeA, nodeB)) {
return equalsNode(nodeA.left, nodeB.left) && equalsNode(nodeA.right, nodeB.right);
}
if (nodesEqualOppositeLeft(nodeA, nodeB) && nodesEqualOppositeRight(nodeA, nodeB)) {
return equalsNode(nodeA.left, nodeB.right) && equalsNode(nodeA.right, nodeB.left);
}
}
return false;
}
public boolean nodesEqualSameLeft(Node<T> nodeA, Node<T> nodeB) {
return nodesEqual(nodeA.left, nodeB.left);
}
public boolean nodesEqualSameRight(Node<T> nodeA, Node<T> nodeB) {
return nodesEqual(nodeA.right, nodeB.right);
}
public boolean nodesEqualOppositeLeft(Node<T> nodeA, Node<T> nodeB) {
return nodesEqual(nodeA.left, nodeB.right);
}
public boolean nodesEqualOppositeRight(Node<T> nodeA, Node<T> nodeB) {
return nodesEqual(nodeA.right, nodeB.left);
}
public boolean nodesEqual(Node<T> nodeA, Node<T> nodeB) {
return (nodeA == null && nodeB == null) || (nodeA != null && nodeA.equals(nodeB));
}
@Override
public String toString() {
return root.toString();
}
}
Node.java
public class Node<T> {
public Node<T> left;
public Node<T> right;
public T value;
public Node(Node<T> left, Node<T> right, T value) {
this.left = left;
this.right = right;
this.value = value;
}
public Node(T value) {
this(null, null, value);
}
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object other) {
Node<T> otherNode = (Node<T>) other;
if (other == null) return false;
if (this.value == null && otherNode.value != null) return false;
if (this.value != null && otherNode.value == null) return false;
return this.value.equals(otherNode.value);
}
@Override
public String toString() {
return String.format("{ \"v\" : %s, \"l\" : %s, \"r\" : %s }", value, left, right);
}
}
输出
{ "v" : 0, "l" : { "v" : 1, "l" : null, "r" : null }, "r" : { "v" : 2, "l" : { "v" : 3, "l" : null, "r" : null }, "r" : null } }
{ "v" : 0, "l" : { "v" : 2, "l" : null, "r" : { "v" : 3, "l" : null, "r" : null } }, "r" : { "v" : 1, "l" : null, "r" : null } }
true