数组到二进制搜索树快速

时间:2016-04-23 05:16:07

标签: algorithm binary-search-tree

给定一个整数数组,有没有办法将它快速转换为二进制搜索树(不平衡)?我已经尝试逐个插入每个元素,但这意味着我必须从头开始遍历每个插入。它工作得很好,但我认为最坏的情况是O(N ^ 2)不平衡,例如数组已排序。鉴于N大,我认为这需要一些时间。

回到我的问题,有没有办法比我说的算法更快地完成这项工作?

例如,给定数组[4,5,2,3,1],有一种快速创建方法吗?

Child class.

4 个答案:

答案 0 :(得分:2)

  

给定一个整数数组,有没有办法将其转换为二进制   快速搜索树(不平衡)?

不确定。在O(n logn)中对数组进行排序,选择数组的中间元素作为根,并将左边的中间元素之前的所有元素插入根,将右边的中间元素插入右边(O(n)时间) 。总复杂度为O(n logn)。例如,如果您有数组:

3, 5, 2, 1, 4

您将其排序为1, 2, 3, 4, 5。中间元素为3,因此您可以创建树

      3
     / \
    2   4
   /     \
  1       5

你可以有两个指向中间元素的指针,你开始将第一个移到左边,另一个移到右边,然后分别将指针指向的元素插入左右子树。

问题是树的高度为n/2,这意味着搜索操作O(n)很慢。为了获得更好的性能,您应该使用自平衡二进制搜索树,例如red-black treeAVL tree

答案 1 :(得分:1)

是的,有一种简单的方法可以从O(nlogn)中的整数数组构建一个平衡的二进制搜索树。

算法如下:

  1. Sort整数数组。这需要O(nlog(n))时间
  2. 在O(n)时间内从排序数组构造BST。只需继续以数组的中间元素为根,并在数组的左半部分和右半部分递归执行此操作。
  3. 修改

    1. 首先,你不能比O(nlog(n))更好地做到这一点,因为那样你就可以在复杂度上对未排序的数组(使用比较)进行排序,而不是O(nlogn)。这是impossible
    2. 如果您最初不必进行排序,可以使用二进制树插入算法为数组的每个元素构建二叉树。
    3. 请参阅Self-balancing BST的任何标准实现。在扫描数组时,在第i次迭代时,你有arr [1 ... i]的BST。现在,您将arr [i + 1]添加到BST(使用插入算法)。

答案 2 :(得分:1)

已经有了很好的解释。下面是从给定数组构造BST的代码。

public static void main(String args[])  
{       
    Node root=null;
    int arr[]=new int[]{99,35,19,0,11,40,5};
    int length=arr.length;
    Arrays.sort(arr); 
    root=constructBST(arr,0,length-1,root);
}
public static Node constructBST(int[]arr,int start,int end,Node root)
{
    if(start>end)
        return null;
    int mid=(start+end)/2;

    if(root==null)
        root=new Node(arr[mid]);

    root.left=constructBST(arr,start,mid-1, root.left);
    root.right=constructBST(arr,mid+1,end, root.right);

    return root;

}

在此之后,只需按顺序遍历pri

答案 3 :(得分:1)

好的,我不确定此解决方案的最佳程度,但这是我写的内容

算法

  1. 对输入数组进行排序
  2. 创建一个采用该排序数组的递归函数
  3. 如果arr的长度为1或为空数组,则在recurisve函数中,返回arr
  4. 否则计算(parseInt(arr.length/2))的中点
  5. 返回数组[midpoint, recuriveFunc(arr[leftToMidPoint]),recuriveFunc(arr[rightToMidpoint])]

用Java代码实现

const arr =  [1,2,3,4,5,6,7]


const recursiveSetValues = (arr) => {
  if (arr.length < 2) return arr
  const midPoint = parseInt(arr.length/2)
  return [arr[midPoint], ...recursiveSetValues(arr.slice(0, midPoint)), ...recursiveSetValues(arr.slice(midPoint+1, arr.length))]
}


const sortArray = arr.sort((a,b) => a-b)
console.log(recursiveSetValues(sortArray))