从已排序的数组创建二进制搜索树

时间:2017-07-01 11:43:57

标签: binary-search-tree

我目前正在检查编码算法。如果我们有以下情况:

给定具有唯一整数元素的排序(递增顺序)数组,编写了一个算法来创建具有最小高度的二叉搜索树。

建议使用以下代码作为解决方案:

TreeNode createMinimalBST(int arr[], int start, int end){
    if (end < start) {
        return null;
    }
    int mid = (start + end) / 2;
    TreeNode n = new TreeNode(arr[mid]);
    n.setLeftChild(createMinimalBST(arr, start, mid - 1));
    n.setRightChild(createMinimalBST(arr, mid + 1, end));
    return n;
}

TreeNode createMinimalBST(int array[]) {
    return createMinimalBST(array, 0, array.length - 1);
}

但是,如果我使用以下数组输入尝试此代码:

[2,4,6,8,10,20]

我执行第一次迭代

createMinimalBST([2,4,6,8,10,20], 0, 5);

以下一行:

int mid = (start + end) / 2; // in Java (0 + 5) / 2  =  2;

将mid作为二叉搜索树的根计算位置编号2,即值6。

但是,此示例中的二叉搜索树应如下所示:

    8
   / \
  4   10
 / \    \
2   6   20 

代码来自信誉良好的来源,但我的直觉是实施不正确。

我错过了什么或者实施不对吗?

3 个答案:

答案 0 :(得分:5)

参考GeeksForGeeks

算法 -

  1.      获取阵列的中间部分并使其成为root。
  2.      左半部分和右半部分递归相同。      
               
    • 从左半边中间开始,让它留给根的孩子              在步骤1中创建。          
    •          
    • 获得右半部分的中间位置并使其成为正确的孩子                在步骤1中创建的root。          
    •      
  3. Wikipedia Link

    代码

     class Node {
    
        int data;
        Node left, right;
    
        Node(int d) {
            data = d;
            left = right = null;
        }
    }
    
    class BinaryTree {
    
        static Node root;
    
        /* A function that constructs Balanced Binary Search Tree 
        from a sorted array */
        Node sortedArrayToBST(int arr[], int start, int end) {
    
            /* Base Case */
            if (start > end) {
                return null;
            }
    
            /* Get the middle element and make it root */
            int mid = (start + end) / 2;
            Node node = new Node(arr[mid]);
    
            /* Recursively construct the left subtree and make it
            left child of root */
            node.left = sortedArrayToBST(arr, start, mid - 1);
    
            /* Recursively construct the right subtree and make it
            right child of root */
            node.right = sortedArrayToBST(arr, mid + 1, end);
    
            return node;
        }
    
        /* A utility function to print preorder traversal of BST */
        void preOrder(Node node) {
            if (node == null) {
                return;
            }
            System.out.print(node.data + " ");
            preOrder(node.left);
            preOrder(node.right);
        }
    
        public static void main(String[] args) {
            BinaryTree tree = new BinaryTree();
            int arr[] = new int[]{2, 4, 6, 8, 10, 12};
            int n = arr.length;
            root = tree.sortedArrayToBST(arr, 0, n - 1);
            System.out.println("Preorder traversal of constructed BST");
            tree.preOrder(root);
        }
    }
    

答案 1 :(得分:1)

排序数组将为您提供平衡的二叉树。这可以在O(n)时间内轻松完成,因为我们可以在O(1)时间内得到中间元素。以下是一个简单的算法,

  
      
  1. 为数组中的中间元素构造一个节点并返回它(这将是基本情况下的根)。

         
        
    1. 从数组的左半部分重复1.将返回值分配给根的左子项。

    2.   
    3. 从数组的右半部分重复1.将返回值分配给根的右子项。

    4.   
  2.   

Java实施

 TreeNode sortedArrayToBST(int arr[], int start, int end) {  
           if (start > end)
              return null; // same as (start+end)/2, avoids overflow.    
           int mid = start + (end - start) / 2;      
           TreeNode node = new
           TreeNode(arr[mid]); 
           node.left = sortedArrayToBST(arr, start, mid-1); 
           node.right = sortedArrayToBST(arr, mid+1, end); 
            return node; 
    }
  

TreeNode sortedArrayToBST(int arr []){return sortedArrayToBST(arr,   0,arr.length-1); }

时间复杂度: ** O(n) ** 以下是sortedArrayToBST()的重复关系。

  

T(n)= 2T(n / 2)+ C

     

T(n) - &gt;大小为n的数组所花费的时间

     

C - &gt;常量(查找数组的中间并将根连接到左侧和右侧   子树需要恒定的时间)

答案 2 :(得分:0)

  • 获取数组的middle,并将其设置为root
  • 递归地对左半部分和右半部分执行相同操作
    • 获取左半部分的middle,使其成为根的left child
    • 获取右半部分的middle并将其设为根的right child

enter image description here

    public TreeNode Convert(int[] array)
    {
        if (array == null || array.Length == 0)
        {
            return null;
        }

        return Convert(array, 0, array.Length - 1);
    }

    private static TreeNode Convert(int[] array, int lo, int hi)
    {
        if (lo > hi)
        {
            return null;
        }

        int mid = lo + (hi - lo) / 2;
        var root = new TreeNode(array[mid]);
        root.Left = Convert(array, lo, mid - 1);
        root.Right = Convert(array, mid + 1, hi);
        return root;
    }

时间复杂度O(n)

来自CodeStandard