代码之家  ›  专栏  ›  技术社区  ›  Aryabhatta

均匀随机奇异二叉树的生成

  •  6
  • Aryabhatta  · 技术社区  · 14 年前

    如果一个二叉树的节点值是1,2,…,N,并且满足以下属性,那么一个由N个节点组成的二叉树就是“奇怪的”

    • 树的每个内部节点正好有一个大于它的子代。
    • 1,2,…,N中的每个数字在树中正好出现一次。

      4
     / \
    5   2
       / \
      1   3
    

    你能给出一个算法来生成一个由n个节点组成的均匀随机二叉树,它在O(n)保证时间内运行吗?

    假设您只能访问随机数生成器,该生成器可以为任何1<=k<=n。假设发电机以O(1)运行。

    一个O(nlogn)时间解决方案也会得到我的支持。

    2 回复  |  直到 13 年前
        1
  •  2
  •   Jason S    14 年前

    啊哈,我想我已经掌握了如何在O(N)时间内创建一个随机堆(之后,使用Greg Kuperberg的答案中的方法转换为“好奇的”二叉树。)

    编辑2

    struct Node {
       Node left, right;
       Object key;
       constructor newNode() { 
         N = new Node; 
         N.left = N.right = null; 
         N.key = null;
       }
    }
    
    function create-random-heap(RandomNumberGenerator rng, int N)
    {
       Node heap = Node.newNode();
       // Creates a heap with an "incomplete" node containing a null, and having
       // both child nodes as null.
    
       List incompleteHeapNodes = [heap];
       // use a vector/array type list to keep track of incomplete heap nodes.
    
       for k = 1:N
       {
          // loop invariant: incompleteHeapNodes has k members. Order is unimportant.
    
         int m = rng.getRandomNumber(k);
         // create a random number between 0 and k-1
         Node node = incompleteHeapNodes.get(m);
         // pick a random node from the incomplete list, 
         // make it a complete node with key k.
         // It is ok to do so since all of its parent nodes
         // have values less than k.
         node.left = Node.newNode();
         node.right = Node.newNode();
         node.key = k;
    
         // Now remove this node from incompleteHeapNodes
         // and add its children. (replace node with node.left,
         // append node.right)
    
         incompleteHeapNodes.set(m, node.left);
         incompleteHeapNodes.append(node.right);
    
         // All operations in this loop take O(1) time.
       }
    
       return prune-null-nodes(heap);
    }
    
    // get rid of all the incomplete nodes.
    function prune-null-nodes(heap)
    {
       if (heap == null || heap.key == null)
          return null;
       heap.left = prune-null-nodes(heap.left);
       heap.right = prune-null-nodes(heap.right);
    }
    
        2
  •  4
  •   Greg Kuperberg    14 年前