Algorithm 关于如何在二叉树算法的第j级检索第i个元素的讨论
我正在一个名为的网站上解决一些问题,最后一个问题是关于一棵二叉树的,其中有: 以一个特殊的工程师和医生家庭为例。这个家庭有 以下规则: 每个人都有两个孩子。工程师的第一个孩子是工程师 工程师,第二个孩子是医生。医生的第一个孩子 他是医生,第二个孩子是工程师。世世代代 医生和工程师从工程师开始 我们可以使用此图表示情况:Algorithm 关于如何在二叉树算法的第j级检索第i个元素的讨论,algorithm,tree,binary-tree,Algorithm,Tree,Binary Tree,我正在一个名为的网站上解决一些问题,最后一个问题是关于一棵二叉树的,其中有: 以一个特殊的工程师和医生家庭为例。这个家庭有 以下规则: 每个人都有两个孩子。工程师的第一个孩子是工程师 工程师,第二个孩子是医生。医生的第一个孩子 他是医生,第二个孩子是工程师。世世代代 医生和工程师从工程师开始 我们可以使用此图表示情况: E / \ E D / \ / \ E D
E
/ \
E D
/ \ / \
E D D E
/ \ / \ / \ / \
E D D E D E E D
考虑到一个人在上面的祖先树中的等级和位置,
找到这个人的职业。注意:在这棵树中,第一个孩子是
被认为是左孩子,第二个被认为是右孩子
由于存在一些空间和时间限制,解决方案不能基于实际构建树,直到达到所需级别并检查哪个元素位于所要求的位置。到现在为止,一直都还不错。我提出的用python编写的解决方案是:
def findProfession(level, pos):
size = 2**(level-1)
shift = False
while size > 2:
if pos <= size/2:
size /= 2
else:
size /= 2
pos -= size
shift = not shift
if pos == 1 and shift == False:
return 'Engineer'
if pos == 1 and shift == True:
return 'Doctor'
if pos == 2 and shift == False:
return 'Doctor'
if pos == 2 and shift == True:
return 'Engineer'
更重要的是,我不理解它背后的逻辑,所以我们来到了这个问题。有人能给我解释一下这个算法吗 让我们按照以下方式对树的节点编号: 1) 根有数字1 2) 节点x的第一个子节点的编号为2*x 3) 节点x的第二个子节点的编号为2*x+1 现在,请注意,每次转到第一个子节点时,职业都保持不变,并且在节点的二进制表示中添加了0。 每次你转到第二个孩子,这个职业就会翻转,你在二进制表示中加上一个1 示例:让我们在第四级(问题图表中的最后一级)中找到第四个节点的职业。首先我们从数字1的根开始,然后转到数字2(10二进制)的第一个子级。然后我们进入2的第二个子元素,即5(101二进制)。最后,我们来看5的第二个子元素11(1011二进制) 请注意,我们开始时只有一位等于1,然后每增加一位到二进制表示中,就改变了这个职业。所以我们翻转职业的次数等于(位数等于1)-1。这一数额的均等决定了职业 这使我们找到了以下解决方案: X=等于1 in[2^(1级)+pos-1]的位数 Y=(X-1)模2 如果Y为0,则答案为“工程师” 否则答案是“医生” 由于2^(级别1)是2的幂,它正好有一位等于1,因此您可以写入: X=等于1英寸[pos-1]的位数 Y=X模2
这与您在问题中提到的解决方案相同。这种类型的序列称为。使用同一棵树,下面演示了它给出正确答案的原因:
p
是0索引位置
b
是p
c
是b
p0
E
b0
c0
/ \
p0 p1
E D
b0 b1
c0 c1
/ \ / \
p0 p1 p2 p3
E D D E
b0 b1 b10 b11
c0 c1 c1 c2
/ \ / \ / \ / \
p0 p1 p2 p3 p4 p5 p6 p7
E D D E D E E D
b0 b1 b10 b11 b100 b101 b110 b111
c0 c1 c1 c2 c1 c2 c2 c3
c
对于工程师来说总是偶数,对于医生来说总是奇数。因此:
index = bin(pos-1).count('1') % 2
return ['Engineer', 'Doctor'][index]
这个问题的答案和解决方案都很好。我希望你能举例说明,这样更容易理解。我不得不读了好几遍。谢谢
index = bin(pos-1).count('1') % 2
return ['Engineer', 'Doctor'][index]