题目:结点编号从0开始,然后给出每个结点左右子树的编号,其中-1表示为NIL,求最大叶子间距
方法一: 方法有点糙,就是求得任意两个结点的间距,从而可得最大叶子间距
1 . 建树
const int N = 10005;
typedef struct {
int parent;
int lchild, rchild;
}BT;
BT bt[N];
int n;
int root;
int max_dis;
void CreatTree() {
int v1, v2;
bool vis[N] = { false };
scanf("%d", &n);
//记录各结点的子结点和父结点
for (int i = 0; i < n; i++) {
scanf("%d%d", &v1, &v2);
bt[i].lchild = v1;
bt[i].rchild = v2;
if (v1 != -1) {
bt[v1].parent = i;
vis[v1] = true;
}
if (v2 != -1) {
bt[v2].parent = i;
vis[v2] = true;
}
}
//根结点为没有父结点的结点
for (int i = 0; i < n; i++) {
if (!vis[i]) {
root = i;
break;
}
}
}
2 . 层次遍历二叉树,将所有叶子结点保存在leaf数组中,统计次数为cnt
3 . 以双循环的方式,以求叶子结点的最近公共祖先的方式求得叶子间距,同时更新max_dis
void com_ancestor() {
int p1, p2;
int dis;
for (int i = 0; i < cnt; i++) {
for (int j = i + 1; j < cnt; j++) {
dis = 0;
p1 = leaf[i].parent;
p2 = leaf[j].parent;
while (p1 != p2) {
dis += 2;
if (p1 == root) break;
if (p2 == root) break;
p1 = leaf[p1].parent;
p2 = leaf[p2].parent;
}
if (p1 == root) {
while (p2 != root) {
dis += 1;
p2 = leaf[p2].parent;
}
}
if (p2 == root) {
while (p1 != root) {
dis += 1;
p1 = leaf[p1].parent;
}
}
if (dis > max_dis) max_dis = dis;
}
}
}