Cómo convertir entre índice basado en 1 y basado en 0

En una representación de matriz binaria de árbol / montón, si usamos un índice basado en 1, tenemos para el nodo i

  • [matemáticas] left \ _child_i = 2i [/ matemáticas]
  • [matemáticas] right \ _child_i = 2i + 1 [/ matemáticas]
  • [matemáticas] parent_i = \ lfloor \ frac {i} {2} \ rfloor [/ math]

En los índices basados ​​en 0, tenemos un mapeo de que el nodo i corresponde al nodo i + 1 en el índice basado en 1. Entonces, obtenemos

  • [matemáticas] left \ _child_i = (2i) + 1 = 2i + 1 [/ matemáticas]
  • [matemáticas] right \ _child_i = (2i + 1) + 1 = 2i + 2 [/ matemáticas]
  • [matemáticas] parent_i = \ lfloor \ frac {i-1} {2} \ rfloor [/ math]

Tenga en cuenta que si bien el uso de índices basados ​​en 0 ahorra 1 ranura de memoria, hace que la implementación sea un poco más compleja. En los índices basados ​​en 1, el padre de 1 es 0 y sabemos que 0 no es un nodo válido. En los índices basados ​​en 0, el padre de 0 es 0, por lo que debemos tratarlo como un caso especial.

La idea es mantener los dos índices uno al lado del otro: un índice basado en uno y un índice diferente. El índice basado en uno lo llamaremos i, y el otro índice lo llamaremos j. Ahora sabemos cómo llegar al padre, al hijo izquierdo y al niño derecho en el índice i:

  • padre (i) = i / 2
  • leftch (i) = 2i
  • rightch (i) = 2i + 1

Pero el problema es que ahora queremos cambiar a nuestro índice j y descubrir cómo llegar a los padres y a los hijos en términos de j. Para hacerlo, definimos funciones para convertir un índice i en un índice j, y viceversa. Dado aj, luego primero convertimos a la i correspondiente, luego vamos al padre o hijo de la manera definida anteriormente, y luego volvemos a convertir a j.

Ejemplo. Ya decidimos que i es el índice basado en 1, ahora dejemos que j sea un índice basado en 0, entonces j (i) = i-1 e i (j) = j + 1. Estamos indexando un montón binario con j y queremos saber los padres y los hijos. Primero convertimos j a i, que es i (j), luego vamos al padre, padre (i (j)) de la forma en que sabemos cómo, y luego volvemos a convertir a un índice j. Todos juntos esto se convierte en j (padre (i (j))) = j (padre (j + 1)) = j ((j + 1) / 2) = ((j + 1) / 2) -1 = (j -1) / 2. Para los niños podemos hacer lo mismo, por ejemplo j (rightch (i (j)) = j (rightch (j + 1)) = j (2 (j + 1) +1) = 2j + 2.