//构造二叉树
public class TreeNode {
int val; //数据域
TreeNode left; //左小孩
TreeNode right; //右小孩
TreeNode() {
left = null;
right = null;
}
TreeNode(int val) {
this.val = val;
left = null;
right = null;
}
public void setVal(int val) {
this.val = val;
}
}
package com.systemClass.tree;
import java.util.LinkedList;
import java.util.Queue;
/**
* projectName:Test
*
* @author brt
* @version 1.0
* description:
* @data 2023/9/14 20:47
*/
public class BinaryTree {
//数组生成二叉树
public static TreeNode arrayToTreeNode(Integer[] array) {
if (array.length == 0) {
return null;
}
TreeNode root = new TreeNode(array[0]);
System.out.println(array[0]);
//链表(Linked list)是一种常见的基础数据结构,是一种线性表
//但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
boolean isLeft = true;
for (int i = 1; i < array.length; i++) {
//peek 返回队列头部的元素,如果队列为空,则返回null
TreeNode node = queue.peek();
if (isLeft) {
if (array[i] != null) {
node.left = new TreeNode(array[i]);
//offer 添加一个元素并返回true,如果队列已满,则返回false
queue.offer(node.left);
}
isLeft = false;
} else {
if (array[i] != null) {
node.right = new TreeNode(array[i]);
queue.offer(node.right);
}
//poll 移除并返问队列头部的元素,如果队列为空,则返回null
queue.poll();
isLeft = true;
}
}
return root;
}
//用于获得树的层数
public static int getTreeDepth(TreeNode root) {
return root == null ? 0 : (1 + Math.max(getTreeDepth(root.left), getTreeDepth(root.right)));
}
//绘画二叉树
private static void writeArray(TreeNode currNode, int rowIndex, int columnIndex, String[][] res, int treeDepth) {
// 保证输入的树不为空
if (currNode == null) {
return;
}
// 先将当前节点保存到二维数组中
res[rowIndex][columnIndex] = String.valueOf(currNode.val);
// 计算当前位于树的第几层
int currLevel = ((rowIndex + 1) / 2);
// 若到了最后一层,则返回
if (currLevel == treeDepth) {
return;
}
// 计算当前行到下一行,每个元素之间的间隔(下一行的列索引与当前元素的列索引之间的间隔)
int gap = treeDepth - currLevel - 1;
// 对左儿子进行判断,若有左儿子,则记录相应的"/"与左儿子的值
if (currNode.left != null) {
res[rowIndex + 1][columnIndex - gap] = "/";
writeArray(currNode.left, rowIndex + 2, columnIndex - gap * 2, res, treeDepth);
}
// 对右儿子进行判断,若有右儿子,则记录相应的"\"与右儿子的值
if (currNode.right != null) {
res[rowIndex + 1][columnIndex + gap] = "\\";
writeArray(currNode.right, rowIndex + 2, columnIndex + gap * 2, res, treeDepth);
}
}
public static void show(TreeNode root) {
if (root == null) {
System.out.println("EMPTY!");
}
// 得到树的深度
int treeDepth = getTreeDepth(root);
// 最后一行的宽度为2的(n - 1)次方乘3,再加1
// 作为整个二维数组的宽度
int arrayHeight = treeDepth * 2 - 1;
int arrayWidth = (2 << (treeDepth - 2)) * 3 + 1;
// 用一个字符串数组来存储每个位置应显示的元素
String[][] res = new String[arrayHeight][arrayWidth];
// 对数组进行初始化,默认为一个空格
for (int i = 0; i < arrayHeight; i++) {
for (int j = 0; j < arrayWidth; j++) {
res[i][j] = " ";
}
}
// 从根节点开始,递归处理整个树
// res[0][(arrayWidth + 1)/ 2] = (char)(root.val + '0');
writeArray(root, 0, arrayWidth / 2, res, treeDepth);
// 此时,已经将所有需要显示的元素储存到了二维数组中,将其拼接并打印即可
for (String[] line : res) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < line.length; i++) {
sb.append(line[i]);//在当前字符串的尾部追加字符串
if (line[i].length() > 1 && i <= line.length - 1) {
i += line[i].length() > 4 ? 2 : line[i].length() - 1;
}
}
System.out.println(sb.toString());
}
}
//生成随机数数组
public static Integer[] randomArr(Integer[] array){
for (int i = 0; i < array.length; i++) {
int num = (int)(Math.random()*100);//随机生成0-100
array[i] = num;
}
return array;
}
public static void main(String[] args) {
Integer arr[] = new Integer[100];
randomArr(arr);
TreeNode treeNode = arrayToTreeNode(arr);
// TreeNode treeNode = arrayToTreeNode(new Integer[]{4, -7, -3, null, null, -9, -3, 9, -7, -4, null, 6, null, -6, -6, null, null, 0, 6, 5, null, 9, null, null, -1, -4, null, null, null, -2});
show(treeNode);
}
}