场景:
.tree结构,node对应应用对象
.应用对象有某个数据属性(BigDecimal类型)
目标:
.查找指定node及下级中某个数据属性值最大的所有节点
主要代码是用于tree节点的findWithMaxVal方法,其它代码用于测试。
package com.example.demo.tree;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
@Slf4j
public class TreeDemo {
TreeNode<Node> root;
/// 构造一个测试树
private void init() {
@Data
class NodeInfo {
private int id;
private BigDecimal val;
private int parent;
public NodeInfo(int id, String val, int parent) {
this.id = id;
this.val = new BigDecimal(val);
this.parent = parent;
}
}
/// tree节点信息
NodeInfo[] nodeInfos = {
new NodeInfo(1, "10", 0),
new NodeInfo(2, "20", 1),
new NodeInfo(3, "30", 1),
new NodeInfo(4, "40", 2),
new NodeInfo(5, "40", 3)
};
Map<Integer, TreeNode<Node>> nodes = new HashMap<>();
Arrays.stream(nodeInfos).forEach(e -> {
Node node = new Node(e.getId());
node.setVal(e.getVal());
nodes.put(e.getId(), new TreeNode<>(e.getId(), node));
});
Arrays.stream(nodeInfos).filter(e -> e.getParent() != 0).forEach(e -> nodes.get(e.getParent()).add(nodes.get(e.getId())));
Arrays.stream(nodeInfos).filter(e -> e.getParent() == 0).forEach(e -> root = nodes.get(e.getId()));
}
/// 查找指定节点及伞下val值最大的节点
@Test
public void f() {
init();
List<TreeNode<Node>> result = new ArrayList<>();
BigDecimal v = findWithMaxVal(root, result, Node::getVal);
log.info("v:{},sizeof result:{}", v, result.size());
}
@FunctionalInterface
public interface ValueGetter extends Function<Node, BigDecimal> {
}
///<
private BigDecimal findWithMaxVal(TreeNode<Node> node, List<TreeNode<Node>> v, ValueGetter getter) {
BigDecimal v0 = v.isEmpty() ? BigDecimal.ZERO : getter.apply(v.get(0).getObject());
int cmp = node.getObject().getVal().compareTo(v0);
if (cmp != -1) {
if (cmp == 1) {
v.clear();
v0 = getter.apply(node.getObject());
}
v.add(node);
}
for (TreeNode<Node> c : node.getChildrens()) {
v0 = findWithMaxVal(c, v, getter);
}
return v0;
}
}
Node.java
package com.example.demo.tree;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Node {
private Integer id;
private BigDecimal val;
public Node(Integer id) {
this.id = id;
}
}
Tree.java
package com.example.demo.tree;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Data
@NoArgsConstructor
public class TreeNode<T> {
private T object;
private Integer id;
private TreeNode<T> parent;
protected List<TreeNode<T>> childrens = new ArrayList<>();
public TreeNode(Integer id, T obj) {
this.id = id;
this.object = obj;
}
public void add(TreeNode<T> node) {
this.childrens.add(node);
node.setParent(this);
}
}