关于树的理论讲解码字不易,直接上连接,收藏不迷路
https://blog.csdn.net/qq_43308275/article/details/119476501
N叉树的java实现
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.function.Predicate;
public class NaryTree<T> implements Iterable<NaryTree<T>> {
/**
* 树节点
*/
private final T node;
/**
* 父节点,根没有父节点
*/
private NaryTree<T> parent;
/**
* 子节点,叶子节点没有子节点
*/
private final List<NaryTree<T>> children;
/**
* 层序遍历结果
*/
private final transient List<List<T>> levelResult = new ArrayList<>();
public NaryTree(T node) {
this.node = node;
this.children = new LinkedList<>();
}
/**
* 添加子节点
*
* @param node
* @return
*/
public NaryTree<T> addChild(T node) {
NaryTree<T> newNode = new NaryTree<>(node);
newNode.parent = this;
this.children.add(newNode);
return newNode;
}
/**
* 前序遍历
*
* @return
*/
public List<T> preTraverse() {
List<T> res = new ArrayList<>();
Stack<NaryTree<T>> stack = new Stack<>();
stack.push(this);
while (!stack.isEmpty()) {
NaryTree<T> current = stack.pop();
res.add(current.node);
//将该节点的子节点从右往左压入栈
for (int i = current.children.size() - 1; i >= 0; i--) {
stack.push(current.children.get(i));
}
}
return res;
}
/**
* 层序遍历
*
* @return
*/
public List<List<T>> levelTraverse() {
traverseNode(this, 0);
return levelResult;
}
/**
* 使用递归的方式实现广度优先遍历
* 时间复杂度O(n)
* 空间复杂度O(log(n))
*
* @param node
* @param level
*/
private void traverseNode(NaryTree<T> node, int level) {
if (levelResult.size() <= level) {
levelResult.add(new ArrayList<>());
}
levelResult.get(level).add(node.node);
for (NaryTree<T> child : node.children) {
traverseNode(child, level + 1);
}
}
/**
* 基于广度优先搜索的遍历
* 时间复杂度:O(n)
* 空间复杂度:O(n)
*
* @return
*/
public List<T> breadthFirstTraverse() {
NaryTree<T> root = this;
List<T> result = new ArrayList<>();
//定义队列
Queue<NaryTree<T>> queue = new LinkedList<>();
//将root根节点加入到当前的队列中
queue.add(root);
while (!queue.isEmpty()) {
//当前层的节点数
int size = queue.size();
//遍历当前层的所有节点
for (int i = 0; i < size; i++) {
//出队
NaryTree<T> node = queue.poll();
assert node != null;
result.add(node.node);
if (node.children.size() > 0) {
//.addAll():将指定集合中的所有元素添加到此集合中。
//将当前节点的节点一次性地加入到队列中
queue.addAll(node.children);
}
}
}
return result;
}
/**
* 根据条件查找符合条件的节点
*
* @param p
* @return
*/
public NaryTree<T> find(Predicate<T> p) {
if (p.test(this.node)) {
return this;
} else if (CollectionUtils.isEmpty(this.children)) {
return null;
} else {
for (NaryTree<T> child : this.children) {
NaryTree<T> res = child.find(p);
if (Objects.nonNull(res)) {
return res;
}
}
return null;
}
}
/**
* 判断是否为根:根没有父节点
*
* @return
*/
public boolean isRoot() {
return parent == null;
}
/**
* 判断是否为叶子节点:子节点没有子节点
*
* @return
*/
public boolean isLeaf() {
return this.children.size() == 0;
}
public T getNode() {
return node;
}
public NaryTree<T> getParent() {
return parent;
}
public List<NaryTree<T>> getChildren() {
return children;
}
@Override
public Iterator<NaryTree<T>> iterator() {
return new NaryTreeIterator<>(this);
}
/**
* 迭代器
*
*/
static class NaryTreeIterator<T> implements Iterator<NaryTree<T>> {
private NaryTree<T> next;
private Stack<NaryTree<T>> stack;
public NaryTreeIterator(NaryTree<T> node) {
this.next = node;
this.stack = new Stack<>();
this.stack.push(node);
}
@Override
public boolean hasNext() {
if (stack.isEmpty()) {
return false;
} else {
NaryTree<T> cur = stack.pop();
next = cur;
for (int i = cur.children.size() - 1; i >= 0; i--) {
stack.push(cur.children.get(i));
}
return true;
}
}
@Override
public NaryTree<T> next() {
return next;
}
}
}