二叉树-求结点m所在子树中包括的结点的数目

来源:互联网 发布:win10游戏优化软件 编辑:程序博客网 时间:2024/03/28 19:25

 


    如上所示,由正整数1,2,3……组成了一颗特殊二叉树。我们已知这个二叉树的最后一个结点是n。现在的问题是,结点m所在的子树中一共包括多少个结点。

    比如,n = 12,m = 3那么上图中的结点13,14,15以及后面的结点都是不存在的,结点m所在子树中包括的结点有3,6,7,12,因此结点m的所在子树中共有4个结点。

输入:

    输入数据包括多行,每行给出一组测试数据,包括两个整数m,n (1 <= m <= n <= 1000000000)。最后一组测试数据中包括两个0,表示输入的结束,这组数据不用处理。

输出:

    对于每一组测试数据,输出一行,该行包含一个整数,给出结点m所在子树中包括的结点的数目。

样例输入:
3 120 0
样例输出:
4
#include<stdio.h>#include<math.h>#include<queue>using namespace std;int m,n,num;queue<int> s;void getCount(int temp) //递归求节点数目{if(temp<=n){num++;getCount(temp*2);getCount(temp*2+1);}}void getCount2()  //使用队列一层层遍历{int top;while(!s.empty()){top=s.front();s.pop();//printf("%d出队\n",top);num++;if(top*2<=n)s.push(top*2);if(top*2+1<=n)s.push(top*2+1);}}void getCount3(int m,int n) //直接用公式计算{int m_depth=log(m*1.0)/log(2.0); //log2(m)int n_depth=log(n*1.0)/log(2.0); //log2(n)int depth=n_depth-m_depth;  //depth层:2^0+2^1+.....+2^(depth-1)=2^(depth)-1num=pow(2.0,depth)-1;//printf("num:%d\n",num);int left=m,right=m; //完全二叉树,m的最后一层的最左边和最右边的值int i,start,end;for(i=0;i<depth;i++){left=left*2;right=right*2+1;}//printf("left:%d    right:%d\n",left,right);if(right<=n)  //最右边的值小于等于最后一个节点nnum=num+right-left+1;else if(left<=n) //最右边的值大于最后一个节点n,并且最左边的节点大于等于nnum=num+n-left+1;}int main(){while(scanf("%d%d",&m,&n)){if(m==0 && n==0)break;num=0;//getCount(m); //超时/*s.push(m);     //内存太大getCount2();*/getCount3(m,n);printf("%d\n",num);}}


0 0
原创粉丝点击