7-5 顺序存储的二叉树的最近的公共祖先问题(25 分)

设顺序存储的二叉树中有编号为ij的两个结点,请设计算法求出它们最近的公共祖先结点的编号和值。

输入格式:

输入第1行给出正整数n),即顺序存储的最大容量;第2行给出n个非负整数,其间以空格分隔。其中0代表二叉树中的空结点(如果第1个结点为0,则代表一棵空树);第3行给出一对结点编号ij

题目保证输入正确对应一棵二叉树,且1

输出格式:

如果ij对应的是空结点,则输出ERROR: T[x] is NULL,其中xij中先发现错误的那个编号;否则在一行中输出编号为ij的两个结点最近的公共祖先结点的编号和值,其间以1个空格分隔。

输入样例1:

15
4 3 5 1 10 0 7 0 2 0 9 0 0 6 8
11 4

输出样例1:

2 3

输入样例2:

15
4 3 5 1 0 0 7 0 2 0 9 0 0 6 8
12 8

输出样例2:

ERROR: T[12] is NULL

这等同于完全二叉树,根据完全二叉树的性质进行操作——第N个节点的左孩子编号为2N,右孩子为2N+1.其实就是不断的除二。注:如果i,j相距很远,需要先对大的进行操作,缩进距离。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#define maxn 1500
using namespace std;
int f[maxn],n;
int f1,f2;
void getf()
{
    if(f[f1]==0)
        printf("ERROR: T[%d] is NULL",f1);
    else if(f[f2]==0)
        printf("ERROR: T[%d] is NULL",f2);
    else
    {
        if(f1>f2)
            swap(f1,f2);
        while(f1<f2)
            f2/=2;
        while(f1!=f2){
            f1/=2;
            if(f1==f2)
                break;
            f2/=2;
        }
        cout<<f1<<" "<<f[f1];
    }
}
using namespace std;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>f[i];
        cin>>f1>>f2;
        getf();
        return 0;
}

非函数版:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#define maxn 1500
int n;
int f[maxn];
using namespace std;
int main()
{
    int i;
    int a,b;
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>f[i];
    cin>>a>>b;
    if(f[a]==0)
        printf("ERROR: T[%d] is NULL",a);
    else if(f[b]==0)
        printf("ERROR: T[%d] is NULL",b);
    else{
        if(a>b){
        swap(a,b);
        }
        while(a<b)
            b/=2;
//        cout<<a<<b;
        while(a!=b)
        {
            a/=2;
            if(a==b)
            break;
            b/=2;
        }
        cout<<a<<" "<<f[a];
        return 0;
    }
}


猜你喜欢

转载自blog.csdn.net/qq_42018521/article/details/80371750