2016 J题 Just anothe binary tree

题意:问大小为n的二叉树的前序遍历的第k个节点是什么。
 解法:根据k来进行DFS,因为k就是这个节点在中序遍历中的下标,那么很好找这个结点v。
假如找到一个结点i,如果i的左子树的节点数为l(l<k),那么由于中序遍历的特性,结点v肯定在i的右子树中,不然就在左子树中,就这样DFS
就可以找到节点V了,现在要的就是如何计算左子树的节点数l了。加入现在DFS到i的时候,这个树有n个节点,那么先不要管最后一层,因为最后
一层可以能不满,那么除去了最后一层后有p个节点(while(p*2<=n) p*=2;)。那么p/2,就分为了两部分,又因为这个p是算多了一个节点的,
所以p/2-1,那么这就是不管最后一层,i的左子树的结点的个数。至于为什么-1,可以画个二叉树来看看,一个3层的满二叉树的节点数是7个的。
但是三层的时候p=8,分成了两部分后,左右子树多了一个节点,那么就要减去一个。那么现在还要加上最后一层的情况,如果最后一层满的情况
那么最后一层应该有p个节点,分为两部分就是p/2,如果最后一层左边满的话,左边也是p/2。如果左边也不满的话就是n-(p-1)个,这里的减1和
上面-1解释一样,既(p-1)为上面满的节点数。所以得出了i的左子树个数l=p/2-1+min(p/2,(n-(p-1));这里的min用于判断最后一层的左边满不满。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int dfs(int v,int n,int k)
{
    int p=1;
    while(p*2<=n)
        p*=2;
    int l=p/2-1+min(n-(p-1),p/2);
    printf("%d %d\n",p,n);
    if((n==1)||(k==l+1))
        return v;
    return l<=k?dfs(2*v+1,n-l-1,k-l-1):dfs(2*v,l,k);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d %d",&n,&k);
        printf("%d\n",dfs(1,n,k));
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值