Jeg tænker stadig, men meget hurtigere end at krydse træet ville være en position_id for enhver mulig position. Hvis du ser på et komplet træ på et bestemt niveau, vil du se, hvad jeg mener - dit eksempel ser sådan ud.
Forbindelserne mellem position og position_id er noget med simpel int aritmetik (div og modulo).
Alle noder i et undertræ deler nogle af disse egenskaber - f.eks. er de direkte subnoder i node 4 (tredje node i anden række) tal
1 + 5 + (3-1)*5 + 1
1 + 5 + (3-1)*5 + 2
1 + 5 + (3-1)*5 + 3
1 + 5 + (3-1)*5 + 4
1 + 5 + (3-1)*5 + 5
Så du ville stadig skulle krydse niveauerne i en løkke, men ikke noderne, hvis du administrerer det positionsnummer i hver node.
Trin 2:
Række r har 5^r elementer (startende med række 0).
Gem rækken og kolonnen i hver knude, i hver række starter kolonnen med 0. Så den anden række er ikke 2,3,4,5,6, men er 1|0, 1|1, 1|2, 1| 3, 1|4.
Hvis din søgerod er 1|1 (række 1, andet element, i dit fine træ med navnet "3"), så har alle børn i række 2
col / 5 = 1
alle børn i række 3 har
col / 25 = 1
og så videre.
Et niveau under node 2|10 er noder 3|(5*10) til 3|(5*11-1) =50 .. 55-1
to niveauer nedenfor er noder 4|(50*5) til 4|(55*5-1)
og så videre.
Trin 3
Pseudokode:
getFreeNode($node){
$rowMax = 100;
$row = $node->row + 1;
$from = 5 * $node->col;
$to = $from + 5;
while($row <= $rowMax){
if ($id = query("select id from member "
."where row = $row and col >= $from and col < $bis"
." and empty_position > 0"))
{
return $id;
}
$row++;
$from *= 5;
$to *= 5;
}
}
insertNode($parent, $node){
$node->row = $parent->row + 1;
$node->col = 5*$parent->col + (5 - $parent->freeNodeCount);
$node->parent_id = $parent->member_id
}
Spørg venligst, hvis der er behov for flere detaljer.