RPA手把手——Python一种求二叉树父节点索引的绝妙写法

艺赛旗 RPA9.0全新首发免费下载 点击下载

http://www.i-search.com.cn/index.html?from=line1

我们都知道堆结构有一个有趣的特性:对于数组 a 的每个元素,总有 a[k] <= a[2k+1] 以及 a[k] <= a[2k+2],假设 k 从 0 开始。
我们可以画出如下的二叉树,其中每个数字指的是元素的下标。

                           0

          1                                 2
		  
  3               4                5               6

7 8 9 10 11 12 13 14

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
那么每个父节点的值都要比它的两个子节点小。

假设我们已经知道了子节点的下标,存在变量 pos 中,如果要求它父节点的下标,根据上面提到的堆的特性,可以将其减去一除以二之后取整,具体操作如下:

parentpos = int((pos - 1) / 2)
pos 为 29 或者 30 时 parentpos 都为 14

下面有另外一种写法:

parentpos = (pos - 1) >> 1
这个是针对二进制的右移一位运算,以数字 29 为例,其二进制为 11101,移位之后是 01110,也就是十进制的 14。以数字 28 为例,其二进制为 11100,移位之后也是 01110,十进制的 14。二进制决定奇偶数的最后一位在右移后直接消失,转换成十进制后的数也从类似22+23+24变成了21+22+2**3的形式,前者正好可以写成后者乘二的结果。

下面分别用 timeit 模块在命令行模式下计算两种写法的运行效率:

C:\Users>python -m timeit “int((30 - 1) / 2)”
10000000 loops, best of 3: 0.134 usec per loop

C:\Users>python -m timeit “(30 - 1) >> 1”
100000000 loops, best of 3: 0.0107 usec per loop
可以看到,运行时间从 0.134 微妙降低到了 0.0107 微妙,是一个数量级的区别。

上一篇:某金融客户财务RPA场景


下一篇:RPA手把手——Python K-Measn 聚类 - 找出原数据集的正态分布中心点