问题
I have created a tree data structure, but I am unable to add two methods that can get me those nodes which are different and those nodes which are same.
The ** ones are those which are similar nodes and the * ones are different nodes.
Tree Structure 1
>23720634 (Root)
**24751368**
**24751324**
**24751324**
**23726962**
**24751382**
**23728776**
**23724832**
**23727632**
**23728875**
**23728813**
*23722966*
**24751324**
**17712706**
Tree Structure 2
>25764379 (Root)
**24751368**
**24751324**
**24751324**
**23726962**
**24751382**
**23728776**
**23724832**
**23727632**
**23728875**
**23728813**
*24742015*
*24763621*
**24751324**
**17712706**
My IMPLEMENTATION OF TREE
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* @param <T>
*/
class TreeNode<T> implements Iterable<TreeNode<T>> {
private final List<TreeNode<T>> elementsIndex;
public T data;
public TreeNode<T> parent;
public List<TreeNode<T>> children;
/**
* @param data =--> data type holder
*/
public TreeNode(T data) {
this.data = data;
this.children = new LinkedList<>();
this.elementsIndex = new LinkedList<>();
this.elementsIndex.add(this);
}
/**
* @param depth --> tree depth
* @return Indentation
*/
private static String createIndent(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append('-');
}
sb.append(">");
return sb.toString();
}
/**
* @param <T> ---> tree data type
* @param node --> tree leaves
* @param appender --> add tree values
*/
public static <T> void printTree(TreeNode<T> node, String appender) {
//System.out.println(appender + node.getData());
node.getChildren().forEach(each -> printTree(each, appender + appender));
}
/**
* @param child --> tree children
* @return child
*/
public TreeNode<T> addChild(TreeNode<T> child) {
child.setParent(this);
this.children.add(child);
return child;
}
/**
* @param children --> tree children
*/
public void addChildren(List<TreeNode<T>> children) {
children.forEach(each -> each.setParent(this));
this.children.addAll(children);
}
/**
* @return data
*/
public T getData() {
return data;
}
/**
* @param data --> tree data type
*/
public void setData(T data) {
this.data = data;
}
/**
* @return parent
*/
public TreeNode<T> getParent() {
return parent;
}
/**
* @param parent --> tree parent
*/
private void setParent(TreeNode<T> parent) {
this.parent = parent;
}
/**
* @return children list
*/
public List<TreeNode<T>> getChildren() {
return children;
}
/**
* @return parent
*/
public boolean isRoot() {
return parent == null;
}
/**
* @return check the size of child
*/
public boolean isLeaf() {
return children.size() == 0;
}
/**
* @param child --> tree children
* @return child node
*/
public TreeNode<T> addChild(T child) {
TreeNode<T> childNode = new TreeNode<>(child);
childNode.parent = this;
this.children.add(childNode);
this.registerChildForSearch(childNode);
return childNode;
}
/**
* @return the depth of the level
*/
public int getLevel() {
if (this.isRoot())
return 0;
else
return parent.getLevel() + 1;
}
/**
* @param node --> tree leaves
*/
private void registerChildForSearch(TreeNode<T> node) {
elementsIndex.add(node);
if (parent != null)
parent.registerChildForSearch(node);
}
public void deleteNode() {
if (parent != null) {
int index = this.parent.getChildren().indexOf(this);
this.parent.getChildren().remove(this);
for (TreeNode<T> each : getChildren()) {
each.setParent(this.parent);
}
this.parent.getChildren().addAll(index, this.getChildren());
} else {
deleteRootNode();
}
this.getChildren().clear();
}
/**
* @return parent after deleting
*/
public TreeNode<T> deleteRootNode() {
if (parent != null) {
throw new IllegalStateException("deleteRootNode not called on root");
}
TreeNode<T> newParent = null;
if (!getChildren().isEmpty()) {
newParent = getChildren().get(0);
newParent.setParent(null);
getChildren().remove(0);
for (TreeNode<T> each : getChildren()) {
each.setParent(newParent);
}
newParent.getChildren().addAll(getChildren());
}
this.getChildren().clear();
return newParent;
}
/**
* @return root
*/
public TreeNode getRoot() {
if (parent == null) {
return this;
}
return parent.getRoot();
}
/**
* @param cmp --> comparing the tree variable
* @return finds the element
*/
public TreeNode<T> findTreeNode(Comparable<T> cmp) {
for (TreeNode<T> element : this.elementsIndex) {
T elData = element.data;
if (cmp.compareTo(elData) == 0)
return element;
}
return null;
}
/**
* @return the root
*/
@Override
public String toString() {
return data != null ? data.toString() : "[data null]";
}
/**
* @return iterator
*/
@Override
public @NotNull Iterator<TreeNode<T>> iterator() {
return new TreeNodeIterator<>(this);
}
/**
* @param treeRoot --> tree root
* @param data --> tree data type
* @return the data else null if not found
*/
public TreeNode<T> search(TreeNode<T> treeRoot, T data) {
Comparable<T> searchCriteria = treeData -> {
boolean nodeOk = treeData.equals(data);
return nodeOk ? 0 : 1;
};
return treeRoot.findTreeNode(searchCriteria);
}
/**
* @param treeRoot --> tree root
* @return the whole tree
*/
public StringBuilder display(TreeNode<T> treeRoot) {
StringBuilder print = new StringBuilder();
print.append('\n');
for (TreeNode<T> node : treeRoot) {
String indent = createIndent(node.getLevel());
print.append(indent).append(node.data);
print.append("\n|");
}
if (print.length() > 0)
print.deleteCharAt(print.length() - 1);
return print;
}
}
/**
* @param <T>
*/
class TreeNodeIterator<T> implements Iterator<TreeNode<T>> {
private final TreeNode<T> treeNode;
private final Iterator<TreeNode<T>> childrenCurNodeIterator;
private ProcessStages doNext;
private TreeNode<T> next;
private Iterator<TreeNode<T>> childrenSubNodeIterator;
/**
* @param treeNode --> tree children
*/
public TreeNodeIterator(TreeNode<T> treeNode) {
this.treeNode = treeNode;
this.doNext = ProcessStages.ProcessParent;
this.childrenCurNodeIterator = treeNode.children.iterator();
}
/**
* @return true if there is nay element
*/
@Override
public boolean hasNext() {
if (this.doNext == ProcessStages.ProcessParent) {
this.next = this.treeNode;
this.doNext = ProcessStages.ProcessChildCurNode;
return true;
}
if (this.doNext == ProcessStages.ProcessChildCurNode) {
if (childrenCurNodeIterator.hasNext()) {
TreeNode<T> childDirect = childrenCurNodeIterator.next();
childrenSubNodeIterator = childDirect.iterator();
this.doNext = ProcessStages.ProcessChildSubNode;
return hasNext();
} else {
this.doNext = null;
return false;
}
}
if (this.doNext == ProcessStages.ProcessChildSubNode) {
if (childrenSubNodeIterator.hasNext()) {
this.next = childrenSubNodeIterator.next();
return true;
} else {
this.next = null;
this.doNext = ProcessStages.ProcessChildCurNode;
return hasNext();
}
}
return false;
}
/**
* @return the next element
*/
@Override
public TreeNode<T> next() {
return this.next;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
enum ProcessStages {
ProcessParent,
ProcessChildCurNode,
ProcessChildSubNode
}
}
When I call the method to get the same nodes, the expected result should be:
**24751368**
**24751324**
**24751324**
**23726962**
**24751382**
**23728776**
**23724832**
**23727632**
**23728875**
**23728813**
**24751324**
**17712706**
When I call the method to get the different nodes, then the expected result to be:
Nodes in Structure 1
*23722966*
Nodes in Structure 2
*24742015*
*24763621*
回答1:
Please show me a better way 😀
public static void main(String[] args) throws Exception{
Path p1 = Path.of("23720634", "24751368", "24751324", "24751324", "23726962", "24751382", "23728776", "23724832", "23727632", "23728875", "23728813", "23722966", "24751324", "17712706");
Path p2 = Path.of("25764379", "24751368", "24751324", "24751324", "23726962", "24751382", "23728776", "23724832", "23727632", "23728875", "23728813", "24742015", "24763621", "24751324", "17712706");
comprec(p1, p2);
}
private static void comprec(Path p1, Path p2){
for(int x1 = 1, x2 = 1, t = 0; ; t++){
try{
if(p1.getName(x1).equals(p2.getName(x2))){
System.out.println("Same Nodes: " + p1.getName(x1++));
x2++;
}else if(p1.getName(x1).equals(p2.getName(x2 + t))){
System.out.println("Nodes in Structure 2: " + p2.getName(x2++));
}else if(p1.getName(x1 + t).equals(p2.getName(x2))){
System.out.println("Nodes in Structure 1: " + p1.getName(x1++));
}else if(p1.getName(x1 + t).equals(p2.getName(x2 + t))){
throw new IllegalArgumentException();
}else continue;
}catch(IllegalArgumentException e){
if(p1.getNameCount() == x1 || p2.getNameCount() == x2){
for(int i = x1; i < p1.getNameCount(); i++)
System.out.println("Nodes in Structure 1: " + p1.getName(i));
for(int i = x2; i < p2.getNameCount(); i++)
System.out.println("Nodes in Structure 2: " + p2.getName(i));
break;
}else{
System.out.println("Nodes in Structure 1: " + p1.getName(x1++));
System.out.println("Nodes in Structure 2: " + p2.getName(x2++));
}
}
t = -1;
}
}
来源:https://stackoverflow.com/questions/66064057/how-to-add-a-function-that-can-compare-two-tree-structure-in-java