经典编程题——二叉树之首个公共父结点

二叉树

题目描述

  1
 /   \
 2     3
 / \   / \
4  5  6  7
/ \ / \ / \ / \
如上图所示,由正整数 1, 2, 3, …组成了一棵无限大的二叉树。
从某一个结点到根结点(编号是1的结点)都有一条唯一的路径,比如从5到根结点的路径是(5, 2, 1),从4到根结点的路径是(4, 2, 1),从根结点1到根结点的路径上只包含一个结点1,因此路径就是(1)。
对于两个结点x和y,假设他们到根结点的路径分别是(x1, x2, … ,1)和(y1, y2,…,1),那么必然存在两个正整数i和j,使得从xi 和yj 开始,有xi = yj,xi + 1 = yj + 1,xi + 2 = yj + 2,…
现在的问题就是,给定x和y,要求他们的公共父结点,即xi(也就是 yj)。

要求:

输入:输入包含多组数据,每组数据包含两个正整数x和y(1≤x, y≤2^31-1)。
输出:对应每一组数据,输出一个正整数xi,即它们的首个公共父结点。

示例:

输入:10 4
输出:2

题目分析

其实这个题很简单,考察的是二叉树的性质。
二叉树从1到n按编码排序,则对于编号为i的结点来说,其左子树为2i,右子树为2i+1。
也就是说,对于编号为i的结点来说,其父结点的编号为i/2。

进而,解题思路如下:
对于输入的两个结点编号x,y:

  • 如果x=y,那么其首个公共结点就是本身;
  • 如果x!=y,那么就求编号大的结点的父结点编号,并更新编号,即如果x>y,那么求x的父结点的编号值,并将该值赋给x。

经过这样的步骤,x和y不断更新为其父结点的编号,那么第一次x=y的编号就是x和y的首个公共父结点。

代码实现

#include<stdio.h>
int main(){
    int x,y;
    while(scanf("%d %d",&x,&y) != EOF){
        while(x!=y){ 
            x>y ? (x/=2) : (y/=2);
        }
        printf("%d\n",x);
    }
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值