我一直在尝试解决这个问题两天,我无法弄清楚如何将数组表示为堆(从左到右)。我尝试在其他网站上寻找答案,但我找不到答案。
问题是有一个给定的数组。例如......
{26,5,3,2,1,1...}
我需要将它转换为这样的无序堆。
26
/ \
5 3
/ \
2 1
到目前为止,我所做的是这个,但我无法弄清楚如何在前往正确的节点之前检查是否首先填充了大多数节点子节点。
package myTest;
public class UnsortedBT {
static int[] unsortedArr = new int[]{26,5,3,2,1,1,10,2,4};
public static void main(String[] args) {
// TODO Auto-generated method stub
UnsortedBT c = new UnsortedBT();
BinaryTree tree = c.new BinaryTree(unsortedArr[0]);
for(int i=1 ;i<unsortedArr.length;i++)
{
BinaryTree newTree = c.new BinaryTree(unsortedArr[i]);
tree.insert(newTree);
}
System.out.println(tree.left.left.right.data);
}
public class BinaryTree{
private BinaryTree right;
private BinaryTree left;
private int data;
public BinaryTree(int s){
data = s;
right = null;
left = null;
}
public int checkTree(){
if(left == null && right == null){
return 1;
}else if(left == null){
return 1 + right.checkTree();
}else if(right == null){
return 1 + left.checkTree();
}else{
return 1 + left.checkTree() + right.checkTree();
}
}
public void insert(BinaryTree bt){
if(left == null){
setLeft(bt);
}else if(right == null){
setRight(bt);
}else{
int leftCheck = left.checkTree();
int rightCheck = right.checkTree();
// The problem is lies here
if(leftCheck==rightCheck||left!=null&&left==null){
left.insert(bt);
}else{
right.insert(bt);
}
}
}
public void setLeft (BinaryTree l){ left = l; }
public void setRight(BinaryTree r){ right = r; }
}
}
答案 0 :(得分:1)
嗯,我认为你正在做DFS,这引起了混乱 你可以用BFS方式做同样的问题
queue.add(new Node(a[0])// Initilize queue with first element
intilize array index counter variable i=0
while(queue.isnotempty)
{
node currentnode=queue.deque();
int left=2*i+1
int right=2*i+2
currentnode.left=new Node(left>array.lenght-1?null:array[left]); //put left variable
currentnode.right=new Node(right>array.lenght-1?null:array[left]); //put right node
if(currennode.left!=null)
queue.enquer(currennode.left);
if(currennode.right!=null)
queue.enquer(currennode.right);
i++;
}
算法适用于bfs我们正在进行BFS遍历 逐个递增索引并将子节点添加到子节点以进行排队,然后将其解除
查找更新的工作代码
package com;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
class Node {
int node;
Node left = null;
Node right = null;
public Node(int value) {
// TODO Auto-generated constructor stub
this.node = node;
}
}
public class ArrayToHeap {
public static void main(String... args)
{
int [] array = new int[]{1,2,3,4,5,6};
Node head=new Node(1);
Queue<Node> queue = new LinkedList();
queue.add(head);
int i=0;
while (!queue.isEmpty())
{
Node currentnode=queue.remove();
int left=2*i+1;
int right=2*i+2;
currentnode.left=left>array.length-1?null:new Node(array[left]);
currentnode.right=right>array.length-1?null:new Node(array[right]);
if(currentnode.left!=null)
queue.add(currentnode.left);
if(currentnode.right!=null)
queue.add(currentnode.right);
i++;
}
}
}
答案 1 :(得分:0)
如果你的节点是i,那么你可以将child指定为2i + 1和2i + 2。
loop(i to n/2){
iParent(i) = i;
iLeftChild(i) = 2*i + 1;
iRightChild(i) = 2*i + 2;
}
尝试这样的事情。
答案 2 :(得分:0)
所以你想从数组中构建一个二叉树。您给出的示例显示树以广度优先顺序表示在数组中。也就是说,数组中索引0处的项是根。接下来的两个项目是root的子项。接下来的四个是那些孩子的孩子等。
正如Aman Sachan在答案中指出的那样,你可以通过以下方式确定一个节点的孩子:
left child index = (node index)*2 + 1
right child index = (node index)*2 + 2
使用该信息,您可以递归地构建树,深度优先,就像对二叉树进行顺序遍历一样。像这样的伪代码。
tree_node build_tree(array, index)
{
// if the index is beyond the end of the array, then there's
// no node here.
if (index >= array.length)
return null;
// create the new node with the proper value.
new_node = new tree_node(array[index]);
// build the left node
new_node.left = build_tree(array, (2*index) + 1);
// and the right node
new_node.right = build_tree(array, (2*index) + 2);
// and then return the newly-built node
return new_node;
}
通过传递数组和第一个索引来调用它:
tree_node root_node = build_tree(array, 0);
另一种解决方案反映了二叉树的广度优先遍历。如果您了解广度优先遍历,您应该能够自己推导出解决方案。