第六章二叉树的编号之小球下落
2017-11-10 15:18
239 查看
有一个基本的知识点要注意的是:对于一个节点K,其左子节点、右子节点的编号分别是2K和2K+1;
Java代码实现如下:
package Practice;
import java.util.Scanner;
public class Book_149 {
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
int D=scan.nextInt(); //树的深度
int I=scan.nextInt(); //小球个数
int max=(int)(Math.pow(2, D))-1; //最大的节点的编号
//初始化一个一维数组用来存储每一个节点的开关状态
//开始时数组元素全为0表示开关全部关闭
int []s=new int[100001];
int k = 0;
for(int i=1;i<=I;i++) {
for(k=1;;) {
if(s[k]==0) {
s[k]=1-s[k];
k=k*2;
}
else {
s[k]=1-s[k];
k=k*2+1;
}
if(k>max)
break;
}
}
System.out.println(k/2);
}
}
常规代码实现起来很简单,但是一旦树高变得很大也就是树拥有太多的子节点,上面的代码里就需要维护一个非常巨大的S数组来存储每一个节点的状态,这样是非常不划算的,因此有了下面的改进。
public class Book_149{
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
int D=scan.nextInt();
int I=scan.nextInt();
int k=1;
for(int d=1;d<D;d++) {
if(I%2==1) {
k=k*2;
I=(I+1)/2;
}else {
k=k*2+1;
I=I/2;
}
}
System.out.println(k);
}
}
书上说当I是奇数时,它是往左走的第(I+1)/2个小球,当I是偶数时,它是向右走的的第I/2个小球,对这句话我的理解,小球每向下走一步,就相当于把上面那一层砍掉,
所以不断对I进行缩进,就表明小球对该层来说是奇的还是偶的,这也就决定了该往哪个方向走,同时每向左或者向右走一次,K就发生变化。