TreeNode *sortedArrayToBST(vector<int> &num) {
     // Start typing your C/C++ solution below
     // DO NOT write int main() function
     if (num.size() <= 0) return NULL;
     if (num.size() == 1) return new TreeNode(num[0]);
     
     vector<int> leftTree(num.begin(), num.begin() + num.size() / 2);
     vector<int> rightTree(num.begin() + num.size() / 2 + 1, num.end());
     
     TreeNode *ret = new TreeNode(num[num.size() / 2]);
     ret->left = sortedArrayToBST(leftTree);
     ret->right = sortedArrayToBST(rightTree);
     return ret;
 }
Exemplo n.º 2
0
    /**
     * Takes the line segment list and determines if it is convex, possibly
     * converting it into a BSP leaf. Otherwise, the list is divided into two
     * halves and recursion will continue on the new sub list.
     *
     * This is done by scanning all of the line segments and finding the one
     * that does the least splitting and has the least difference in numbers
     * of line segments on either side (why is this valued? -ds).
     *
     * If the line segments on the left side are convex create another leaf
     * else put the line segments into the left list.
     *
     * If the line segments on the right side are convex create another leaf
     * else put the line segments into the right list.
     *
     * @param node  Tree node for the block containing the line segments to
     *              be partitioned.
     *
     * @return  Newly created BSP subtree; otherwise @c nullptr (degenerate).
     */
    BspTree *partitionSpace(LineSegmentBlockTreeNode &node)
    {
        LOG_AS("Partitioner::partitionSpace");

        BspElement *bspElement = nullptr; ///< Built BSP map element at this node.
        BspTree *rightBspTree  = nullptr;
        BspTree *leftBspTree   = nullptr;

        // Pick a line segment to use as the next partition plane.
        if(LineSegmentSide *partSeg = choosePartition(node))
        {
            // Reconfigure the half-plane for the next round of partitioning.
            hplane.configure(*partSeg);

            /*
            LOG_TRACE("%s, segment side %p %i (segment #%i) %s %s")
                    << hplane.partition().asText()
                    << partSeg
                    << partSeg->lineSideId()
                    << lineSegments.indexOf(&partSeg->line())
                    << partSeg->from().origin().asText()
                    << partSeg->to().origin().asText();
            */

            // Take a copy of the current partition - we'll need this for any
            // BspNode we produce later.
            Partition partition(hplane.partition());

            // Create left and right block trees.
            /// @todo There should be no need to use additional independent
            ///       structures to contain these subsets.
            LineSegmentBlockTree rightTree(node.userData()->bounds());
            LineSegmentBlockTree leftTree(node.userData()->bounds());

            // Partition the line segements into two subsets according to their
            // spacial relationship with the half-plane (splitting any which
            // intersect).
            divideSegments(node, rightTree, leftTree);
            node.clear();

            addPartitionLineSegments(rightTree, leftTree);

            // Take a copy of the geometry bounds for each child/sub space
            // - we'll need this for any BspNode we produce later.
            AABoxd rightBounds = segmentBounds(rightTree);
            AABoxd leftBounds  = segmentBounds(leftTree);

            // Recurse on each suspace, first the right space then left.
            rightBspTree = partitionSpace(rightTree);
            leftBspTree  = partitionSpace(leftTree);

            // Collapse degenerates upward.
            if(!rightBspTree || !leftBspTree)
                return rightBspTree? rightBspTree : leftBspTree;

            // Make a new BSP node.
            bspElement = new BspNode(partition, rightBounds, leftBounds);
        }
        else
        {
            // No partition required/possible -- already convex (or degenerate).
            LineSegmentSides segments = collectAllSegments(node);
            node.clear();

            subspaces.append(ConvexSubspaceProxy());
            ConvexSubspaceProxy &convexSet = subspaces.last();

            convexSet.addSegments(segments);

            for(LineSegmentSide *seg : segments)
            {
                // Attribute the segment to the convex subspace.
                seg->setConvexSubspace(&convexSet);

                // Disassociate the segment from the block tree.
                seg->setBlockTreeNode(nullptr);
            }

            // Make a new BSP leaf.
            /// @todo Defer until necessary.
            BspLeaf *leaf = new BspLeaf;

            // Attribute the leaf to the convex subspace.
            convexSet.setBspLeaf(leaf);

            bspElement = leaf;
        }

        // Make a new BSP subtree and link up the children.
        BspTree *subtree = new BspTree(bspElement, nullptr/*no parent*/, rightBspTree, leftBspTree);
        if(rightBspTree) rightBspTree->setParent(subtree);
        if(leftBspTree)  leftBspTree->setParent(subtree);

        return subtree;
    }