目标:构建简单的二叉树,实现简单的功能
功能:
- 构建树结构
- 添加节点
- 先序、后序、中序遍历
- 反转树
- 计算高度或深度
- 广度优先算法
难点
- 删除:建议参考以下博客文章
https://blog.csdn.net/isea533/article/details/80345507/
- 旋转:建议参考以下博客文章
https://blog.csdn.net/saasanken/article/details/80796178
代码:
package com.miracle.study.tree;
import org.junit.jupiter.api.Test;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Miracle
* @date 2021/4/8 14:25
*/
public class BSTree<T extends Comparable<T>> {
/**
* 根节点
*/
private BSTNode<T> root;
/**
* 节点定义
*
* @param <T>
*/
static class BSTNode<T> {
/**
* 数据
*/
public T data;
/**
* 左节点
*/
public BSTNode<T> left;
/**
* 右节点
*/
public BSTNode<T> right;
public BSTNode(T data) {
this.data = data;
}
}
private void add(BSTNode<T> node, T data) {
// 根据值的大小判断是左节点还是右节点
if (node.data.compareTo(data) <= 0) {
// 判断当前节点的左节点是否为空,是就直接赋值,不是就迭代下去
if (node.left == null) {
node.left = new BSTNode<>(data);
} else {
add(node.left, data);
}
} else {
// 判断当前节点的右节点是否为空,是就直接赋值,不是就迭代下去
if (node.right == null) {
node.right = new BSTNode<>(data);
} else {
add(node.right, data);
}
}
}
/**
* 添加节点
*
* @param data
*/
public void add(T data) {
if (root == null) {
this.root = new BSTNode<>(data);
} else {
add(root, data);
}
}
private void preOrder(BSTNode<T> node, ArrayList<T> tList) {
if (node == null) {
return;
}
tList.add(node.data);
preOrder(node.left, tList);
preOrder(node.right, tList);
}
/**
* 先序排序
*
* @return
*/
public List<T> preOrder() {
var tList = new ArrayList<T>();
preOrder(this.root, tList);
return tList;
}
private void postOrder(BSTNode<T> node, ArrayList<T> tList) {
if (node == null) {
return;
}
postOrder(node.left, tList);
postOrder(node.right, tList);
tList.add(node.data);
}
/**
* 后序排序
*
* @return
*/
public List<T> postOrder() {
var tList = new ArrayList<T>();
postOrder(this.root, tList);
return tList;
}
private void inOrder(BSTNode<T> node, ArrayList<T> tList) {
if (node == null) {
return;
}
inOrder(node.left, tList);
tList.add(node.data);
inOrder(node.right, tList);
}
/**
* 中序排序
*
* @return
*/
public List<T> inOrder() {
var tList = new ArrayList<T>();
inOrder(this.root, tList);
return tList;
}
private void reverse(BSTNode<T> node) {
if (node == null) {
return;
}
var cacheNode = node.left;
node.left = node.right;
node.right = cacheNode;
reverse(node.left);
reverse(node.right);
}
/**
* 反转树
*/
public void reverse() {
reverse(this.root);
}
private int height(BSTNode<T> node) {
if (node == null) {
return 0;
}
// +1 表示每层+1,max取值是当前节点中两个分支节点取最大层数的值。
return Math.max(height(node.left), height(node.right)) + 1;
}
/**
* 获取高度/深度
*
* @return
*/
public int height() {
return height(this.root);
}
/**
* 广度优先算法
* @return
*/
public List<T> bfs() {
if (this.root == null){
return Collections.EMPTY_LIST;
}
// 创建队列
var queue = new LinkedList<BSTNode<T>>();
// 返回集合
var tList = new ArrayList<T>();
// 将根节点加入到队列
queue.addLast(root);
// 不断循环直到队列为空
while (queue.size() > 0) {
// 弹出节点
var node = queue.poll();
// 数据记录进入集合中
tList.add(node.data);
// 判断是否存在左节点,存在就添加到队列中
if (node.left != null) {
queue.addLast(node.left);
}
// 判断是否存在右节点,存在就添加到队列中
if (node.right != null) {
queue.addLast(node.right);
}
}
// 返回数据集合
return tList;
}
@Test
public void test() {
var tree = new BSTree<Integer>();
tree.add(10);
tree.add(7);
tree.add(5);
tree.add(8);
tree.add(15);
tree.add(30);
tree.add(21);
// 先序遍历
tree.preOrder().forEach(data -> System.out.print(data + " "));
System.out.println();
// 后序遍历
tree.postOrder().forEach(data -> System.out.print(data + " "));
System.out.println();
// 中序遍历
tree.inOrder().forEach(data -> System.out.print(data + " "));
System.out.println();
// 反转树
tree.reverse();
// 获取高度
System.out.println(tree.height());
// 获取广度
tree.bfs().forEach(data -> System.out.print(data + " "));
System.out.println();
}
}