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]