【问题标题】:Create an unsorted heap (left to right) using given array使用给定的数组创建一个未排序的堆(从左到右)
【发布时间】:2016-11-16 06:24:28
【问题描述】:

我已经尝试解决这个问题两天了,但我不知道如何将数组表示为堆(从左到右)。我尝试在其他网站上寻找答案,但找不到。

问题是有一个给定的数组。比如……

{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; }        
}
}

【问题讨论】:

  • 这篇博客文章和后面的文章应该可以帮助你:blog.mischel.com/2013/09/29/a-better-way-to-do-it-the-heap
  • 这是排序堆先生。我正在做未排序的。
  • 没有“无序堆”这样的东西。堆具有特定的结构,实际上是有序的。看起来您正在尝试从任意数组创建平衡的左填充二叉树。碰巧您选择的数组表示创建了一个最大堆树。

标签: arrays algorithm heap binary-tree


【解决方案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++;
    }



}
}

【讨论】:

  • 我回家后试试这个,谢谢!为什么你使用 queue.add 然后突然 queue.enquer ?这背后的原因是什么?
  • 我认为这里有一个错误。分配节点时,您总是在创建一个新节点。您的三元运算符在错误的位置。你应该有currentnode.left=left&gt;array.length-1?null:new Node(array[left])
  • 大家好,这是一个伪代码,只是为了粗略了解如何解决可能需要处理的小错误或边界值约束。我只是想说明如何解决
【解决方案2】:

所以你想从数组中构建一棵二叉树。您给出的示例显示树在数组中以广度优先顺序表示。也就是说,数组中索引 0 处的项目是根。接下来的两项是根的子项。接下来的四个是那些孩子的孩子,等等。

正如 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);

还有另一种解决方案反映了二叉树的广度优先遍历。如果您了解广度优先遍历,您应该能够自己得出解决方案。

【讨论】:

    【解决方案3】:

    如果您的节点是 i,那么您可以将子节点分配为 2i + 1 和 2i + 2。

    loop(i to n/2){
       iParent(i)     = i;
       iLeftChild(i)  = 2*i + 1;
       iRightChild(i) = 2*i + 2;
    }
    

    试试这样的。

    【讨论】:

    • 对不起,我不明白你的解决方案。你能进一步解释一下吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多