习题4.5 顺序存储的二叉树的最近的公共祖先问题 (25point(s))
设顺序存储的二叉树中有编号为i和j的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值。
Example:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
#define CHECK(x) if(H[x]==0) {printf("ERROR: T[%d] is NULL\n", x);return 0;}
#define MARK(x) {int h=x;while(h){V[h]+=1;h>>=1;}}
int main()
{
int N;
cin >> N;
vector<int> H;
vector<int> V;
H.reserve(N+1);
V.reserve(N+1);
for(int k = 1; k <= N; k++) {
cin >> H[k];
V[k] = 0;
}
int i, j;
cin >> i >> j;
CHECK(i);
CHECK(j);
MARK(i);
MARK(j)
while(i) {
if(V[i] == 2) { cout << i << ' ' << H[i] << endl; break;}
i >>= 1;
}
return 0;
}
思路:
标记 i,j 到根结点的路径,然后在从i或者j开始重新检查路径,如果某个结点被标记2次,那么这个就是共同祖先