Algorithm 将后序二叉树遍历索引转换为级别顺序(宽度优先)索引

Algorithm 将后序二叉树遍历索引转换为级别顺序(宽度优先)索引,algorithm,computer-science,theory,binary-tree,graph-theory,Algorithm,Computer Science,Theory,Binary Tree,Graph Theory,假设一棵完整的二叉树,每个节点都可以用它在给定的树遍历算法中出现的位置来寻址 例如,高度为3的简单完整树的节点索引如下所示: 宽度优先(又名等级顺序): 邮购部门优先: 6 / \ 2 5 / \ / \ 0 1 3 4 给出了树的高度和后序遍历中的索引 如何根据这些信息计算宽度优先指数?暴力方式,直到找到更好的答案: 从后序数组/索引构建树,使每个节点的值成为当前数组索引 使用索引:索引的前半部分是左子树,后半部分是右子树,中间节点是根。为每个

假设一棵完整的二叉树,每个节点都可以用它在给定的树遍历算法中出现的位置来寻址

例如,高度为3的简单完整树的节点索引如下所示:

宽度优先(又名等级顺序):

邮购部门优先:

     6
   /   \
  2     5
 /  \  /  \
0   1  3  4
给出了树的高度和后序遍历中的索引


如何根据这些信息计算宽度优先指数?

暴力方式,直到找到更好的答案:

  • 从后序数组/索引构建树,使每个节点的值成为当前数组索引 使用索引:索引的前半部分是左子树,后半部分是右子树,中间节点是根。为每个子树递归

  • 遍历树的宽度优先,将计算出的宽度优先索引作为映射对的值放入映射中,键为节点的值<代码>映射.放置(node.value,tree\u visitor.current\u index)

  • 查询映射,传递所需的键(post-order节点的索引)以获得相应的宽度优先节点的索引


  • 我认为它必须迭代/递归地计算。话虽如此,有人会在37秒钟内通过简单的单行计算来投票给我。尽管如此,它可以通过递归地思考来解决。考虑深度优先后序遍历的简单树(1-Basic):

       3
      / \
     1   2
    
    从递归的角度来看,这就是您需要考虑的全部内容。您要么在子树(3)的根上,要么在子树(1)的左侧,要么在右侧(2)。如果你是根,那么你就完了。否则,左子树和右子树是相同的,右子树中的后序遍历索引等于对应的左子树索引+子树中的节点数

    以下代码在
    O(log n)
    中执行此计算。对于深度为10(1023个节点)的树,它最多在10次迭代(递归)中计算索引值

    它跟踪给定节点的深度,并根据处理的是左子树还是右子树来计算宽度第一行的位置。请注意,这使用基于1的索引值。我发现用这些术语来考虑它更简单(深度为2的树中有3个节点,后序遍历中最顶端的节点是3)。还要注意的是,它认为树深度为1就有一个节点(我不确定这是否是典型的约定)

       3
      / \
     1   2
    
    // Recursively compute the given post-order traversal index's position
    // in the tree:  Its position in the given level and its depth in the tree.
    void ComputePos( int treedepth, int poindex, int *levelposition, int *nodedepth )
    {
        int nodes;
        int half;
    
        // compute number of nodes for this depth.
        assert( treedepth > 0 );
        nodes = ( 1 << ( treedepth )) - 1;
        half = nodes / 2;   // e.g., 7 / 2 = 3
    
        //printf( "poindex = %3d, Depth = %3d, node count = %3d", poindex, treedepth, nodes );
    
        (*nodedepth)++;
    
        if ( poindex == nodes ) {
            // This post-order index value is the root of this subtree
            //printf( "  Root\n" );
            return;
        }
        else if ( poindex > half ) {
            // This index is in the right subtree
            //printf( "  Right\n" );
            poindex -= half;
            *levelposition = 2 * *levelposition + 1;
        }
        else {
            // Otherwise it must be in the left subtree
            //printf( "  Left\n" );
            *levelposition = 2 * *levelposition;
        }
    
        treedepth -= 1;
        ComputePos( treedepth, poindex, levelposition, nodedepth );
    }
    
    int main( int argc, char* argv[] )
    {
        int levelposition = 0;   // the 0-based index from the left in a given level
        int nodedepth = 0;  // the depth of the node in the tree
        int bfindex;
        int treedepth = atoi( argv[1] );   // full depth of the tree (depth=1 means 1 node)
        int poindex = atoi( argv[2] ); // 1-based post-order traversal index
    
        ComputePos( treedepth, poindex, &levelposition, &nodedepth );
    
        //printf( "ComputePos( %d, %d ) = %d, %d\n", treedepth, poindex, levelposition, nodedepth );
    
        // Compute the breadth-first index as its position in its current
        // level plus the count of nodex in all the levels above it.
        bfindex = levelposition + ( 1 << ( nodedepth - 1 ));
        printf( "Post-Order index %3d = breadth-first index %3d\n", poindex, bfindex );
    
        return 0;
    }
    
                15
              /    \
             /      \
            /        \
           /          \
          /            \
         7             14     
        / \            / \    
       /   \          /   \   
      3     6       10    13  
     /\    / \      /\    / \ 
    1  2  4   5    8  9  11  12
    
    
    [C:\tmp]for /l %i in (1,1,15) do po2bf 4 %i
    Post-Order index   1 = breadth-first index   8
    Post-Order index   2 = breadth-first index   9
    Post-Order index   3 = breadth-first index   4
    Post-Order index   4 = breadth-first index  10
    Post-Order index   5 = breadth-first index  11
    Post-Order index   6 = breadth-first index   5
    Post-Order index   7 = breadth-first index   2
    Post-Order index   8 = breadth-first index  12
    Post-Order index   9 = breadth-first index  13
    Post-Order index  10 = breadth-first index   6
    Post-Order index  11 = breadth-first index  14
    Post-Order index  12 = breadth-first index  15
    Post-Order index  13 = breadth-first index   7
    Post-Order index  14 = breadth-first index   3
    Post-Order index  15 = breadth-first index   1