二叉树的编号(UVA679)(二叉树入门)

    这道题目个人感觉出的很不好,当然,是输入输出不好。该题要求先输入测试数据的总数,这个正常,可还要求要以-1作为输入结束标记,搞不懂出题人怎么想的。

    说说这道题的做法,书上提供了两种方法。一种是用数组模拟,还有一种是用数学方法。模拟的不再多说。
    我们知道一开始的时候所有都是关闭的。对于每一个节点来说,如果一个球是掉到它上面的第奇数个,则往左子树掉,否则往右子数掉。假设深度为D,则每一个球都要掉D-1次。我们用这种数学方法可以直接模拟第I个球掉落过程。
#include <cstdio>
#include <cstring>
int main ()
{
    int  n ,D, T;
    scanf("%d", &n);
    while(n--)
    {
        while(scanf("%d", &D)==1)
        {
            if(D==-1)
                return 0;
            scanf("%d", &T);
            int k=1;
            for(int i=1; i<=D-1; i++)
            {
                if(T%2)
                {
                    k=k*2;
                    T=(T+1)/2;
                }
                else
                {
                    k=k*2+1;
                    T=T/2;
                }
            }
            printf("%d\n",k);
        }
    }
    return 0;
}
我们假设D为4,I为5;(我程序里为I为T)

我们手工模拟一遍程序运行来理解一下。显然要掉3次
第一次: I为5,是掉在第一个节点上的奇数球,所以k=2*k(往左子树掉),也就是掉到了节点2上去,那么这个5号球是掉在2节点上的球的奇数还是偶数呢?程序下一步:I=(I+1)/2,也就是掉在二节点的第三个球,以此类推,只要模拟一遍,理解并不难。

对于这样一个节点,我们一定要关注一个结论:左字树是2k,右子树是2k+1,。

你可能感兴趣的:(数据结构,二叉树)