如何从数组表示构建不完整的二叉树
How to build an incomplete binary tree from array representation
如果输入是一个数组,其中null
表示没有节点。
输入:
[1, 2, 3, null, 5, null, 7]
请假设我已经检查了输入。
对于每个array[i]
,它的父array[i / 2]
不会是null
(递归,所以根不能是null
)。
如何用这样的逻辑关系构建一棵树:
1
/ \
2 3
\ \
5 7
每个节点应该由一个 TreeNode
对象表示:
class TreeNode {
public:
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
我找到了一个 blog here 在那里建造了一棵完整的树
但是如果树像上面说的那样不完整,如何整齐高效地做呢?
测试数据:
[输入数组]
[-64,12,18,-4,-53,null,76,null,-51,null,null,-93,3,null,-31,47,null,3,53,-81,33,4,null,-51,-44,-60,11,null,null,null,null,78,null,-35,-64,26,-81,-31,27,60,74,null,null,8,-38,47,12,-24,null,-59,-49,-11,-51,67,null,null,null,null,null,null,null,-67,null,-37,-19,10,-55,72,null,null,null,-70,17,-4,null,null,null,null,null,null,null,3,80,44,-88,-91,null,48,-90,-30,null,null,90,-34,37,null,null,73,-38,-31,-85,-31,-96,null,null,-18,67,34,72,null,-17,-77,null,56,-65,-88,-53,null,null,null,-33,86,null,81,-42,null,null,98,-40,70,-26,24,null,null,null,null,92,72,-27,null,null,null,null,null,null,-67,null,null,null,null,null,null,null,-54,-66,-36,null,-72,null,null,43,null,null,null,-92,-1,-98,null,null,null,null,null,null,null,39,-84,null,null,null,null,null,null,null,null,null,null,null,null,null,-93,null,null,null,98]
当将二叉树实现为数组时,有一个
两种表示法如何反映一个的清晰可视化
另一个,并复习下划线的数学结构
关系。
如果我们考虑索引为 0 的数组,数学关系可以
被分解成这样,
- 根节点的索引为 0
对于i:th
节点(i
是数组索引)我们有(验证)
- 节点的left-child有索引
2i + 1
- 节点的right-child有索引
2(i + 1)
- 节点的parent有索引
floor((i-1)/2)
所以,对于二叉树
如果我们让-
表示null
,则表示为
[0:a, 1:b, 2:c, 3:d, 4:e, 5:-, 6:-, 7:-, 8:-, 9:g, 10:-, 11:-, 12:-, 13:-, 14:-]
因此,现在要从数组创建 OO 表示,您只需应用这些索引规则。所以,既然你知道根节点是 a
那么我们就可以得到它的 children at:
- 左:
2*0 + 1 = 1 => b
- 右:
2*(0 + 1) = 2 => c
伪代码
for (int idx = 0; 2*(idx + 1) < len(arr); idx++) {
if (arr[idx] == null) {
// There is no node to add for this index
continue;
}
TreeNode t = null;
if (idx == 0) {
// Root node case
t = TreeNode(val: arr[idx]);
binary_tree.add(id: idx, node: t);
}
// We do not know if these exist yet
int left_idx = 2*idx + 1;
int right_idx = 2*(idx + 1);
if (left_idx >= len(arr)) {
// left_idx is out of bounds with respect to the array,
// and by extension so would the right node be
continue;
}
TreeNode left = null;
TreeNode right = null;
if (arr[left_idx] != null) {
// This node has never been encountered before
// and it is non-null so it must be created.
//
// Since we know we have a root node then there is
// no need to check if the tree already contains this
// node, it simply is not possible. Ditto for the right
// node.
left = TreeNode(val: arr[left_idx]);
binary_tree.add(id: left_idx, node: left);
}
if (right_idx >= len(arr)) {
// There cannot be a right child
continue;
}
if (arr[right_idx] != null) {
// This node has never been encountered before
// and it is non-null so it must be created.
right = TreeNode(val: arr[right_idx]);
binary_tree.add(id: right_idx, right);
}
// It does not matter if left or right is null
t.set_left(left)
t.set_right(right)
}
就用递归遍历使用数组索引遍历节点,用Integer允许null。
private TreeNode array2Tree(Integer[] data,TreeNode root, int index){
if(index >= data.length){
return root;
}
if(data[index] != null){
TreeNode temp = new TreeNode(data[index]);
root = temp;
root.left = array2Tree(data,root.left,2*index+1);
root.right = array2Tree(data,root.right,2*index+2);
}
return root;
}
我想这个例子可以解释你的想法。
array : [5,4,8,11,null,17,4,7,null,null,null,5]
Tree :
5
/ \
4 8
/ / \
11 17 4
/ /
7 5
以上所有答案都将输入数组视为一棵完整的树。所以 left.child=2idx+1 , right.child = 2idx+2 但实际上是错误的。
因为那些
[5,4,8,11,null,17,4,7,null,null,null,5]
[5,4,8,11,null,17,4,7,null,null,null,null,null,5,null]
不同
这是我的解决方案
public static TreeNode createTree(Integer[] array) {
if (array == null || array.length==0) {
return null;
}
Queue<TreeNode> treeNodeQueue = new LinkedList<>();
Queue<Integer> integerQueue = new LinkedList<>();
for (int i = 1; i < array.length; i++) {
integerQueue.offer(array[i]);
}
TreeNode treeNode = new TreeNode(array[0]);
treeNodeQueue.offer(treeNode);
while (!integerQueue.isEmpty()){
Integer leftVal = integerQueue.isEmpty() ? null : integerQueue.poll();
Integer rightVal = integerQueue.isEmpty() ? null : integerQueue.poll();
TreeNode current = treeNodeQueue.poll();
if (leftVal !=null) {
TreeNode left = new TreeNode(leftVal);
current.left = left;
treeNodeQueue.offer(left);
}
if (rightVal !=null){
TreeNode right = new TreeNode(rightVal);
current.right = right;
treeNodeQueue.offer(right);
}
}
return treeNode;
}
在Java中:
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode() {}
public TreeNode(int val) { this.val = val; }
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
/**
* Create a tree from array using levels i.e {-2,3,4,null,null,5,null,null,null,null,null, 6 } becomes 2 le-> 3, 2 re->4, 4 le->5, 5 le->6
* @param arr the arr to be converted to a tree
* @return
*/
public static TreeNode createTreeFromArray(Integer[] arr){
TreeNode root = new TreeNode();
return insertLevelOrder(arr, root, 0);
}
static TreeNode insertLevelOrder(Integer[] arr, TreeNode root,
int i)
{
// Base case for recursion
if (i < arr.length) {
if(arr[i] == null)
return null;
TreeNode temp = new TreeNode(arr[i]);
root = temp;
// insert left child
root.left = insertLevelOrder(arr, root.left,
2* i + 1);
// insert right child
root.right = insertLevelOrder(arr, root.right,
2* i + 2);
}
return root;
}
}
谢谢史蒂文。我将 Steven 的 Java 代码转换为 Python。它对我有用!
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def creatBTree(data):
if data == None or len(data) == 0:
return None
treeNodeQueue = []
integerQueue = []
for i in range(1,len(data)):
print(i)
integerQueue.append(data[i])
treeNode = TreeNode(data[0])
treeNodeQueue.append(treeNode)
while integerQueue:
if integerQueue:
leftVal = integerQueue.pop(0)
if integerQueue:
rightVal = integerQueue.pop(0)
current = treeNodeQueue.pop(0)
if leftVal is not None:
left = TreeNode(leftVal)
current.left = left
treeNodeQueue.append(left)
if rightVal is not None:
right = TreeNode(rightVal)
current.right = right
treeNodeQueue.append(right)
return treeNode
如果输入是一个数组,其中null
表示没有节点。
输入:
[1, 2, 3, null, 5, null, 7]
请假设我已经检查了输入。
对于每个array[i]
,它的父array[i / 2]
不会是null
(递归,所以根不能是null
)。
如何用这样的逻辑关系构建一棵树:
1
/ \
2 3
\ \
5 7
每个节点应该由一个 TreeNode
对象表示:
class TreeNode {
public:
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
我找到了一个 blog here 在那里建造了一棵完整的树
但是如果树像上面说的那样不完整,如何整齐高效地做呢?
测试数据:
[输入数组]
[-64,12,18,-4,-53,null,76,null,-51,null,null,-93,3,null,-31,47,null,3,53,-81,33,4,null,-51,-44,-60,11,null,null,null,null,78,null,-35,-64,26,-81,-31,27,60,74,null,null,8,-38,47,12,-24,null,-59,-49,-11,-51,67,null,null,null,null,null,null,null,-67,null,-37,-19,10,-55,72,null,null,null,-70,17,-4,null,null,null,null,null,null,null,3,80,44,-88,-91,null,48,-90,-30,null,null,90,-34,37,null,null,73,-38,-31,-85,-31,-96,null,null,-18,67,34,72,null,-17,-77,null,56,-65,-88,-53,null,null,null,-33,86,null,81,-42,null,null,98,-40,70,-26,24,null,null,null,null,92,72,-27,null,null,null,null,null,null,-67,null,null,null,null,null,null,null,-54,-66,-36,null,-72,null,null,43,null,null,null,-92,-1,-98,null,null,null,null,null,null,null,39,-84,null,null,null,null,null,null,null,null,null,null,null,null,null,-93,null,null,null,98]
当将二叉树实现为数组时,有一个 两种表示法如何反映一个的清晰可视化 另一个,并复习下划线的数学结构 关系。
如果我们考虑索引为 0 的数组,数学关系可以 被分解成这样,
- 根节点的索引为 0
对于i:th
节点(i
是数组索引)我们有(验证)
- 节点的left-child有索引
2i + 1
- 节点的right-child有索引
2(i + 1)
- 节点的parent有索引
floor((i-1)/2)
所以,对于二叉树
如果我们让-
表示null
,则表示为
[0:a, 1:b, 2:c, 3:d, 4:e, 5:-, 6:-, 7:-, 8:-, 9:g, 10:-, 11:-, 12:-, 13:-, 14:-]
因此,现在要从数组创建 OO 表示,您只需应用这些索引规则。所以,既然你知道根节点是 a
那么我们就可以得到它的 children at:
- 左:
2*0 + 1 = 1 => b
- 右:
2*(0 + 1) = 2 => c
伪代码
for (int idx = 0; 2*(idx + 1) < len(arr); idx++) {
if (arr[idx] == null) {
// There is no node to add for this index
continue;
}
TreeNode t = null;
if (idx == 0) {
// Root node case
t = TreeNode(val: arr[idx]);
binary_tree.add(id: idx, node: t);
}
// We do not know if these exist yet
int left_idx = 2*idx + 1;
int right_idx = 2*(idx + 1);
if (left_idx >= len(arr)) {
// left_idx is out of bounds with respect to the array,
// and by extension so would the right node be
continue;
}
TreeNode left = null;
TreeNode right = null;
if (arr[left_idx] != null) {
// This node has never been encountered before
// and it is non-null so it must be created.
//
// Since we know we have a root node then there is
// no need to check if the tree already contains this
// node, it simply is not possible. Ditto for the right
// node.
left = TreeNode(val: arr[left_idx]);
binary_tree.add(id: left_idx, node: left);
}
if (right_idx >= len(arr)) {
// There cannot be a right child
continue;
}
if (arr[right_idx] != null) {
// This node has never been encountered before
// and it is non-null so it must be created.
right = TreeNode(val: arr[right_idx]);
binary_tree.add(id: right_idx, right);
}
// It does not matter if left or right is null
t.set_left(left)
t.set_right(right)
}
就用递归遍历使用数组索引遍历节点,用Integer允许null。
private TreeNode array2Tree(Integer[] data,TreeNode root, int index){
if(index >= data.length){
return root;
}
if(data[index] != null){
TreeNode temp = new TreeNode(data[index]);
root = temp;
root.left = array2Tree(data,root.left,2*index+1);
root.right = array2Tree(data,root.right,2*index+2);
}
return root;
}
我想这个例子可以解释你的想法。
array : [5,4,8,11,null,17,4,7,null,null,null,5]
Tree :
5
/ \
4 8
/ / \
11 17 4
/ /
7 5
以上所有答案都将输入数组视为一棵完整的树。所以 left.child=2idx+1 , right.child = 2idx+2 但实际上是错误的。 因为那些
[5,4,8,11,null,17,4,7,null,null,null,5]
[5,4,8,11,null,17,4,7,null,null,null,null,null,5,null]
不同
这是我的解决方案
public static TreeNode createTree(Integer[] array) {
if (array == null || array.length==0) {
return null;
}
Queue<TreeNode> treeNodeQueue = new LinkedList<>();
Queue<Integer> integerQueue = new LinkedList<>();
for (int i = 1; i < array.length; i++) {
integerQueue.offer(array[i]);
}
TreeNode treeNode = new TreeNode(array[0]);
treeNodeQueue.offer(treeNode);
while (!integerQueue.isEmpty()){
Integer leftVal = integerQueue.isEmpty() ? null : integerQueue.poll();
Integer rightVal = integerQueue.isEmpty() ? null : integerQueue.poll();
TreeNode current = treeNodeQueue.poll();
if (leftVal !=null) {
TreeNode left = new TreeNode(leftVal);
current.left = left;
treeNodeQueue.offer(left);
}
if (rightVal !=null){
TreeNode right = new TreeNode(rightVal);
current.right = right;
treeNodeQueue.offer(right);
}
}
return treeNode;
}
在Java中:
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode() {}
public TreeNode(int val) { this.val = val; }
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
/**
* Create a tree from array using levels i.e {-2,3,4,null,null,5,null,null,null,null,null, 6 } becomes 2 le-> 3, 2 re->4, 4 le->5, 5 le->6
* @param arr the arr to be converted to a tree
* @return
*/
public static TreeNode createTreeFromArray(Integer[] arr){
TreeNode root = new TreeNode();
return insertLevelOrder(arr, root, 0);
}
static TreeNode insertLevelOrder(Integer[] arr, TreeNode root,
int i)
{
// Base case for recursion
if (i < arr.length) {
if(arr[i] == null)
return null;
TreeNode temp = new TreeNode(arr[i]);
root = temp;
// insert left child
root.left = insertLevelOrder(arr, root.left,
2* i + 1);
// insert right child
root.right = insertLevelOrder(arr, root.right,
2* i + 2);
}
return root;
}
}
谢谢史蒂文。我将 Steven 的 Java 代码转换为 Python。它对我有用!
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def creatBTree(data):
if data == None or len(data) == 0:
return None
treeNodeQueue = []
integerQueue = []
for i in range(1,len(data)):
print(i)
integerQueue.append(data[i])
treeNode = TreeNode(data[0])
treeNodeQueue.append(treeNode)
while integerQueue:
if integerQueue:
leftVal = integerQueue.pop(0)
if integerQueue:
rightVal = integerQueue.pop(0)
current = treeNodeQueue.pop(0)
if leftVal is not None:
left = TreeNode(leftVal)
current.left = left
treeNodeQueue.append(left)
if rightVal is not None:
right = TreeNode(rightVal)
current.right = right
treeNodeQueue.append(right)
return treeNode