本文先将数组转换成二叉树,再将二叉树转换成数组。可以将不平衡的二叉树转换为数组。
原理就是数组表示二叉树时,下标是n的左、右节点的下标分别是2n+1、2n+2。利用递归来实现。
一、设计树节点对象时候,可以引入深度depth、index(在数组中索引)两个属性,方便从树节点转换为数组。
import org.junit.Test;
import java.util.Arrays;
public class Traversal {
/*
45
/ \
34 5
/ \ \
12 2 3
/ / \ \
33 76 8 44
*/
static class MyTreeNode {
Integer value;
MyTreeNode left;
MyTreeNode right;
//有这个就很容易计算出数组大小了
int depth;
int index;
MyTreeNode(Integer value) {
this.value = value;
}
public int getDepth() {
return depth;
}
}
/**
* 数组转换成树
*/
@Test
public void arrayToTree() {
Integer[] arr = {45, 34, 5, 12, 2, null, 3, 33, null, 76, 8, null, null, null, 44};
MyTreeNode root = generateTreeFromArray(arr, 0);
}
/**
* 树转换成数组
*/
@Test
public void treeToArray() {
//生成一棵树。数组没有元素情况,本例不考虑
Integer[] arr = {45, 34, 5, 12, 2, null, 3, 33, null, 76, 8, null, null, null, 44};
MyTreeNode root = generateTreeFromArray(arr, 0);
//根据depth,计算数组size
int arraySize = (int) Math.pow(2, root.depth) - 1;
Integer[] dst = new Integer[arraySize];
//再将node转换成对应的数组,根据index填充
generateArrayFromTree(dst,root);
System.out.println(Arrays.toString(dst)); //打印验证
}
private static void generateArrayFromTree(Integer[] arr,MyTreeNode node){
if(node==null){
return;
}
arr[node.index]=node.value;
generateArrayFromTree(arr,node.left);
generateArrayFromTree(arr,node.right);
}
private static MyTreeNode generateTreeFromArray(Integer[] arr, int index) {
if (index > arr.length - 1 || arr[index] == null) {
return null;
}
MyTreeNode myTreeNode = new MyTreeNode(arr[index]);
myTreeNode.left = generateTreeFromArray(arr, 2 * index + 1);
myTreeNode.right = generateTreeFromArray(arr, 2 * index + 2);
int leftDepth = myTreeNode.left == null ? 0 : myTreeNode.left.depth;
int rightDepth = myTreeNode.right == null ? 0 : myTreeNode.right.depth;
myTreeNode.depth = Math.max(leftDepth, rightDepth) + 1;
myTreeNode.index = index;
return myTreeNode;
}
}
二、可以有一点改动,不引入index变量,同样达到目标,其他和上面方法一样
package alg;
import org.junit.Test;
import java.util.Arrays;
public class Traversal2 {
/*
45
/ \
34 5
/ \ \
12 2 3
/ / \ \
33 76 8 44
*/
static class MyTreeNode {
Integer value;
MyTreeNode left;
MyTreeNode right;
//有这个就很容易计算出数组大小了
int depth;
MyTreeNode(Integer value) {
this.value = value;
}
public int getDepth() {
return depth;
}
}
/**
* 数组转换成树
*/
@Test
public void arrayToTree() {
Integer[] arr = {45, 34, 5, 12, 2, null, 3, 33, null, 76, 8, null, null, null, 44};
MyTreeNode root = generateTreeFromArray(arr, 0);
}
/**
* 树转换成数组
*/
@Test
public void treeToArray() {
//生成一棵树。数组没有元素情况,本例不考虑
Integer[] arr = {45, 34, 5, 12, 2, null, 3, 33, null, 76, 8, null, null, null, 44};
MyTreeNode root = generateTreeFromArray(arr, 0);
//根据depth,计算数组size
int arraySize = (int) Math.pow(2, root.depth) - 1;
Integer[] dst = new Integer[arraySize];
//再将node转换成对应的数组,根据index填充
generateArrayFromTree(dst,root,0);
System.out.println(Arrays.toString(dst)); //打印验证
}
private static void generateArrayFromTree(Integer[] arr,MyTreeNode node,int index){
if(node==null){
return;
}
arr[index]=node.value;
generateArrayFromTree(arr,node.left,2*index+1);
generateArrayFromTree(arr,node.right,2*index+2);
}
private static MyTreeNode generateTreeFromArray(Integer[] arr, int index) {
if (index > arr.length - 1 || arr[index] == null) {
return null;
}
MyTreeNode myTreeNode = new MyTreeNode(arr[index]);
myTreeNode.left = generateTreeFromArray(arr, 2 * index + 1);
myTreeNode.right = generateTreeFromArray(arr, 2 * index + 2);
int leftDepth = myTreeNode.left == null ? 0 : myTreeNode.left.depth;
int rightDepth = myTreeNode.right == null ? 0 : myTreeNode.right.depth;
myTreeNode.depth = Math.max(leftDepth, rightDepth) + 1;
return myTreeNode;
}
}