Här är en lösning som låter dig flytta en nod till valfri position i trädet med bara en enda indataparameter - nodens nya vänstra position (newpos).
I grund och botten finns det tre uppsättningar:
- Skapa nytt utrymme för underträdet.
- Flytta underträdet till detta utrymme.
- Ta bort det gamla utrymmet som lämnats av underträdet.
I psuedo-sql ser det ut så här:
//
* -- create new space for subtree
* UPDATE tags SET lpos = lpos + :width WHERE lpos >= :newpos
* UPDATE tags SET rpos = rpos + :width WHERE rpos >= :newpos
*
* -- move subtree into new space
* UPDATE tags SET lpos = lpos + :distance, rpos = rpos + :distance
* WHERE lpos >= :tmppos AND rpos < :tmppos + :width
*
* -- remove old space vacated by subtree
* UPDATE tags SET lpos = lpos - :width WHERE lpos > :oldrpos
* UPDATE tags SET rpos = rpos - :width WHERE rpos > :oldrpos
*/
Variabeln :distance är avståndet mellan den nya och gamla positionen, :width är storleken på underträdet och :tmppos används för att hålla reda på underträdet som flyttas under uppdateringarna. Dessa variabler definieras som:
// calculate position adjustment variables
int width = node.getRpos() - node.getLpos() + 1;
int distance = newpos - node.getLpos();
int tmppos = node.getLpos();
// backwards movement must account for new space
if (distance < 0) {
distance -= width;
tmppos += width;
}
För ett komplett kodexempel, se min blogg på
https://rogerkeays.com/how -att-flytta-en-nod-i-kapslade-uppsättningar-med-sql
Om du gillar den här lösningen, vänligen rösta upp.