我认为这必须通过迭代/递归计算来完成。尽管如此,可能会有人在37秒内提供一个简单的单行计算方法,并给我点个踩。然而,可以通过递归思考来解决它。考虑深度优先后序遍历的简单树(基于1):
3
/ \
1 2
从递归的角度来看,这就是你需要考虑的所有内容。你要么在子树的根部(3),要么在左侧子树(1),要么在右侧子树(2)。如果你在根处,那么就完成了。否则,左右子树是相同的,右子树的后序遍历索引等于相应的左子树索引+子树中节点的数量。
以下代码以O(log n)
的时间复杂度执行此计算。对于深度为10(1023个节点)的树,它最多在10次迭代(递归)中计算出索引值。
它跟踪给定节点的深度,并基于其处理左侧或右侧子树来计算广度优先行位置。请注意,它使用基于1的索引值。我发现用这种方式更容易理解(深度为2的树有3个节点,在后序遍历中,最上面的节点是3)。还请注意,它认为树的深度为1有一个节点(我不确定这是否是典型惯例)。
void ComputePos( int treedepth, int poindex, int *levelposition, int *nodedepth )
{
int nodes;
int half;
assert( treedepth > 0 );
nodes = ( 1 << ( treedepth )) - 1;
half = nodes / 2;
(*nodedepth)++;
if ( poindex == nodes ) {
return;
}
else if ( poindex > half ) {
poindex -= half;
*levelposition = 2 * *levelposition + 1;
}
else {
*levelposition = 2 * *levelposition;
}
treedepth -= 1;
ComputePos( treedepth, poindex, levelposition, nodedepth );
}
int main( int argc, char* argv[] )
{
int levelposition = 0;
int nodedepth = 0;
int bfindex;
int treedepth = atoi( argv[1] );
int poindex = atoi( argv[2] );
ComputePos( treedepth, poindex, &levelposition, &nodedepth );
bfindex = levelposition + ( 1 << ( nodedepth - 1 ));
printf( "Post-Order index %3d = breadth-first index %3d\n", poindex, bfindex );
return 0;
}
以下是计算出的数值,针对以下树形结构(深度为4),显示了后序遍历索引值(从1开始计数)。
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