初学的水平, 欢迎批评指正
LeetCode上都有生成二叉树的题解,在此简单解释部分内容.
数组生成二叉树
层序遍历生成二叉树, 每层结点入栈出栈,size 是上层结点个数,控制出栈结点数量
public static TreeNode levelForm(Integer[] source) {
if (source == null || source.length == 0)
return null;
Queue<TreeNode> Queue = new LinkedList<>();
TreeNode root = new TreeNode(source[0]);
Queue.add(root);
int j = 1;
Pos:
while (!Queue.isEmpty()) {
int size = Queue.size();
for (int i = 0; i < size; i++) {
if (j == source.length) {
break Pos;
}
TreeNode t = Queue.poll();
if (source[j] != null) {
t.left = new TreeNode(source[j]);
Queue.add(t.left);
}
j++;
if (j == source.length) {
break Pos;
}
if (source[j] != null) {
t.right = new TreeNode(source[j]);
Queue.add(t.right);
}
j++;
}
}
return root;
}
控制台打印二叉树
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
left | 3:root | right | |||||
/ | \ | ||||||
1 | 5 | ||||||
/ | \ | / | \ | ||||
0 | 2 | 4 | 6 |
- 将树在完全二叉树中的结点坐标位置补齐.
- 结点数字有最大长度maxNumLen , 或者可以写死最大数字占位宽度, 占位字符串是placeholder
- 确定每个结点在完全二叉树中的编号, 最下面一层均匀分布.完全二叉树的性质, 左子编号是其双亲编号的二倍.
- null以空格占位, 左右相邻的结点至少间隔一个固定长度maxNumLen .
- 从下往上, 双亲结点位置坐标, 取左右子位置坐标的平均值.
- 左子头上 ‘/’, 右子头上’\’, 在数字末位对齐
打印结果
IdPos数组的索引既是结点的在完全二叉树中的编号, 取值是位置坐标
[8, 4, 1211, 211, -6, 1011, 1554, 11111, -311, 5, 7, 9111, 11, 13, 10005]
getIdPos:
[0, 7, 3, 11, 1, 5, 9, 13, 0, 2, 4, 6, 8, 10, 12, 14]
8
/ \
4 1211
/ \ / \
211 -6 1011 1554
/ \ / \ / \ / \
11111 -311 5 7 9111 11 13 10005
代码如下
import java.util.*;
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode() {
}
public TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
public static List<List<Integer>> levelOrder(TreeNode root) {
if (root == null)
return new ArrayList<>();
Queue<TreeNode> Queue = new LinkedList<>();
List<List<Integer>> list = new ArrayList<>();
Queue.add(root);
while (!Queue.isEmpty()) {
int size = Queue.size();
ArrayList<Integer> list1 = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode t = Queue.poll();
list1.add(t.val);
if (t.left != null) {
Queue.add(t.left);
}
if (t.right != null) {
Queue.add(t.right);
}
}
if (list1.size() > 0) {
list.add(list1);
}
}
return list;
}
static int[] idPos;
static int minVal = Integer.MAX_VALUE;
static int maxVal = Integer.MIN_VALUE;
static HashMap<Integer, Integer> nodeIds = new HashMap<>();
public static int treeGraph(TreeNode root, int id) {
if (root == null)
return 0;
nodeIds.put(id, root.val);
if (root.val < minVal) {
minVal = root.val;
}
if (root.val > maxVal) {
maxVal = root.val;
}
int a = treeGraph(root.left, id << 1);
int b = treeGraph(root.right, (id << 1) + 1);
return a >= b ? a + 1 : b + 1;
}
static int treeSizeLimit = 0;
static String placeHolder4Num = " ";
// static String placeHolder4Num = " ";
public static StringBuilder formGraph(TreeNode root) {
int depth = treeGraph(root, 1);
if (depth == 0) {
return new StringBuilder();
}
int limit = 1 << depth;
treeSizeLimit = limit >> 1;
idPos = new int[limit];
int deepestLen = limit - 1;
int index = deepestLen - 1;
//最下面一层均匀分布
for (int i = limit - 1; i >= treeSizeLimit; i--) {
idPos[i] = index;
index -= 2;
}
treeGraphPos(1);
int maxNumLen = Math.max(getLenOfNum(maxVal), getLenOfNum(minVal));
//占位字符串是placeholder
StringBuilder placeholder = new StringBuilder();
for (int i = 0; i < maxNumLen; i++) {
placeholder.append(placeHolder4Num);
}
StringBuilder[] numberBuilder = new StringBuilder[depth];
StringBuilder[] branchBuilder = new StringBuilder[depth];
for (int i = 0; i < depth; i++) {
numberBuilder[i] = new StringBuilder();
branchBuilder[i] = new StringBuilder();
}
for (int j = 1, level = 0; j <= treeSizeLimit; level++, j <<= 1) {
int id = j;
for (; id < j << 1 && nodeIds.get(id) == null; id++) ;
Integer val;
for (int i = 0; i < idPos[id]; i++) {
numberBuilder[level].append(placeholder);
branchBuilder[level].append(placeholder);
}
int lastPos = idPos[id];
for (; id < j << 1; id++) {
val = nodeIds.get(id);
if (val == null) {
continue;
}
int pos = idPos[id];
if (pos != lastPos) {
for (int i = lastPos + 1; i < pos; i++) {
numberBuilder[level].append(placeholder);
branchBuilder[level].append(placeholder);
}
lastPos = pos;
}
int len = getLenOfNum(val);
for (int i = 0; i < maxNumLen - len; i++) {
numberBuilder[level].append(placeHolder4Num);
}
numberBuilder[level].append(val);
for (int i = 1; i < maxNumLen; i++) {
branchBuilder[level].append(placeHolder4Num);
}
branchBuilder[level].append(id % 2 == 0 ? '/' : '\\');
}
}
StringBuilder res = new StringBuilder(numberBuilder[0]);
res.append('\n');
for (int i = 1; i < depth; i++) {
res.append(branchBuilder[i]);
res.append('\n');
res.append(numberBuilder[i]);
res.append('\n');
}
return res;
}
public static void treeGraphPos(int id) {
//递归的终止条件
if (id >= treeSizeLimit) {
return;
}
treeGraphPos(id << 1);
treeGraphPos((id << 1) + 1);
idPos[id] = (idPos[id << 1] + idPos[(id << 1) + 1]) >> 1;
}
public static int getLenOfNum(int n) {
int count = 0;
if (n < 0) {
count++;
} else {
n = -n;
}
while (n <= -10) {
count++;
n /= 10;
}
count++;
return count;
}
public static TreeNode levelForm(Integer[] source) {
if (source == null || source.length == 0)
return null;
Queue<TreeNode> Queue = new LinkedList<>();
TreeNode root = new TreeNode(source[0]);
Queue.add(root);
int j = 1;
Pos:
while (!Queue.isEmpty()) {
int size = Queue.size();
for (int i = 0; i < size; i++) {
if (j == source.length) {
break Pos;
}
TreeNode t = Queue.poll();
if (source[j] != null) {
t.left = new TreeNode(source[j]);
Queue.add(t.left);
}
j++;
if (j == source.length) {
break Pos;
}
if (source[j] != null) {
t.right = new TreeNode(source[j]);
Queue.add(t.right);
}
j++;
}
}
return root;
}
public static int[] getIdPos() {
return idPos;
}
public static void main(String[] args) {
List<Integer[]> list = Arrays.asList(
new Integer[]{0, 2, 4, 1, null, 3, -1, 5, 1, null, 6, 12, 8},
new Integer[]{8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15},
new Integer[]{},
new Integer[]{2, 3},
new Integer[]{8, 4, 1211, 211, -6, 1011, 1554, 11111, -311, 5, 7, 9111, 11, 13, 10005}
);
for (Integer[] ints : list) {
System.out.println(Arrays.toString(ints));
TreeNode node = levelForm(ints);
levelOrder(node);
StringBuilder builder = formGraph(node);
System.out.println("getIdPos:");
System.out.println(Arrays.toString(TreeNode.getIdPos()));
System.out.println(builder);
System.out.println("------------ ");
}
}
}