問題與解答
問題描述
對一棵完全二叉樹,采用自上而下、自左往右的方式從1開始編號,我們已知這個二叉樹的最后一個結點是n,現在的問題是結點m所在的子樹一共包括多少個結點?
輸入格式
輸入數據包括多行,每行給出一組測試數據,包括兩個整數m,n (1 <= m <= n <= 1000000000)。0 0表示輸入結束。
輸出格式
對於每一組測試數據,輸出一行,該行包含一個整數,給出結點m所在子樹中包括的結點的數目。
樣例輸入
3 12
0 0
樣例輸出
4
#include<stdio.h>
#include<queue> //隊列
using namespace std;
int main()
{
int m,n,x,num;
queue<int> Q; //創建隊列保存子樹結點
while(scanf("%d%d", &m,&n)!=EOF && m && n) //多點測試
{
num = 0;
Q.push(m); //加入第一個結點
num++; //sum++
while(1)
{
/*取出當前結點*/
x = Q.front();
Q.pop();
/*添加當前結點的子樹結點*/
if(2*x <= n) {Q.push(2*x); num++;} //每添加一個結點sum++
else break;
if(2*x+1 <= n) {Q.push(2*x+1); num++;}
else break;
}
while(!Q.empty()) Q.pop(); //不要忽略
printf("%d\n", num);
}
}
題后反思: 本質是BFS
- 這題的本質是遍歷結點
- 遍歷有兩種實現方式:BFS\DFS
- BFS: 利用 隊列 暫存元素
- DFS: 利用 棧 暫存元素
- 這題原解法的實質就是BFS, 而且不難知道,這題也可以用DFS(遞歸)求解,不過這往往涉及樹的二叉鏈表實現,會比較繁瑣