小球下落开关的c语言,小球下落(二叉树)!!!!

小球下落 !!!

问题描述 :

有一颗二叉树,做大的深度为D,所有叶子的深度都相同,所有节点从上到下从左到右的编号为 1,2,3,4....2^(D-1)

在节点1处放一个小球,他会往下落,每个内节点上都有一个开关,初始化的时候都是关着的,当每次有小球落到一个

开关的时候,他的状态就会变化,当小球到达一个内节点的时候,如果开关是关闭的,就往左走,否则就往右走,直到

走到叶子节点

0818b9ca8b590ca3270a3433284dd417.png

如图所示 :

D <= 20 输入最多包含1000组数据:

想输入一个D表示二叉树的深度,在输入I表示第几个小球

输出第I个小球最后落入的叶子节点数目

样例 :

4 2

3 4

10 1

2 2

8 128

16 12345

输出:

12

7

512

3

255

36358

问题分析 :

我一开始做的时候就一直没有发现,这个二叉树是有规律的,但是现在发现还是不算太晚的.

任何一个内节点,都有两个子子节点,就像他的两个儿子一样,除了,最后的一行,最后一行不是内节点

这个节点的分布很有意思,任何一个内节点的左子节点都是这个父节点的二倍,(我说的是他们标识的数字)

任何右子节点都是这个父节点而倍加一,如果 父节点上面的数字是,k,这个父节点的左子节点是2*k,这个父节点的

右子节点是2*k+1,有了这个规律解决这个题就方便多了.

伪代码 :

使用动态分配的原则,calloc

建立了n个节点,

1.使用while,while(i < I)

2.num = count ; count = Array[count] == 0 ?    2*count(左节点) : 2*count+1(右节点);

3.Array[num] = Array[num] == 0 ? 1 : 0;  //这个就是在遇到小球后开关状态变化

4.if(count*2 > D) {i == I && 输入count;count = 1;i++}

0818b9ca8b590ca3270a3433284dd417.png

在这里我又一次的使用了 逻辑与操作, 其实这个操作我非常的喜欢,在时间上说,他一定比if要快

而且十分的简单,但是要注意,逻辑与的左右的两条语句必须都要有返回值,如果没有返回值的话

他会报错的.

在这里我使用的动态分配的函数并不是malloc函数,而是calloc函数这个函数其实和

malloc函数差不多,但是使用起来,我感觉还是malloc比较好用,后者之所以我使用他,

是因为使用了这个函数之后就不用初始化了,这个calloc这个函数不用初始化就省去了

一部分的时间开销,其实我想,这部分的时间开销还是存在的,因为你在申请内存的时候

也要进行初始化,这样的话也是花费时间的,不过我实在是懒得写for这样的循环给这个

数组初始化了,这个总的来说这个函数还是有一点优点的......

在linux man手册中 :

void *malloc(size_t size);

void *calloc(size_t nmemb,size_t size);

nmemb是你要申请的空间个数,size是每一个空间占用几个字节

如果实在是看不懂可以看一下他们的介绍,对自己还是有一点帮助的......

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值