Table of Contents
Fetching ...

Fast and simple unrooted dynamic forests

Benjamin Aram Berendsohn

TL;DR

This work introduces dynamic forests built on search trees on trees (STTs), focusing on unrooted forests where traditional link-cut trees (LCTs) are less competitive. It formalizes 2-cut STTs, provides explicit, constant-time rotations, and implements Link, Cut, and PathWeight via a NodeToRoot primitive with multiple variants of NodeToRoot (MoveToRootTT and several SplayTT variants). The authors present a modular Rust library that compares STT-based methods against LCTs, showing that STT-based approaches excel on unrooted forests while LCTs remain faster for rooted forests; among STT variants, Greedy SplayTT often offers the best practical performance. The results demonstrate the practicality and competitiveness of STT-based dynamic forests, highlighting their simpler rotation primitive and potential advantages in unrooted settings, with open questions around further optimizations and real-world applications.

Abstract

A dynamic forest data structure maintains a forest (and associated data like edge weights) under edge insertions and deletions. Dynamic forests are widely used to solve online and offline graph problems. Well-known examples of dynamic forest data structures are link-cut trees [Sleator and Tarjan '83] and top trees [Alstrup, Holm, de Lichtenberg, and Thorup '05], both of which need O(log n) time per operation. While top trees are more flexible and arguably easier to use, link-cut trees are faster in practice [Tarjan and Werneck '10]. In this paper, we propose an alternative to link-cut trees. Our data structure is based on search trees on trees (STTs, also known as elimination trees) and an STT algorithm [Berendsohn and Kozma '22] based on the classical Splay trees [Sleator and Tarjan '85]. While link-cut trees maintain a hierarchy of binary search trees, we maintain a single STT. Most of the complexity of our data structure lies in the implementation of the STT rotation primitive, which can easily be reused, simplifying the development of new STT-based approaches. We implement several variants of our data structure in the Rust programming language, along with an implementation of link-cut trees for comparison. Experimental evaluation suggests that our algorithms are faster when the dynamic forest is unrooted, while link-cut trees are faster for rooted dynamic forests.

Fast and simple unrooted dynamic forests

TL;DR

This work introduces dynamic forests built on search trees on trees (STTs), focusing on unrooted forests where traditional link-cut trees (LCTs) are less competitive. It formalizes 2-cut STTs, provides explicit, constant-time rotations, and implements Link, Cut, and PathWeight via a NodeToRoot primitive with multiple variants of NodeToRoot (MoveToRootTT and several SplayTT variants). The authors present a modular Rust library that compares STT-based methods against LCTs, showing that STT-based approaches excel on unrooted forests while LCTs remain faster for rooted forests; among STT variants, Greedy SplayTT often offers the best practical performance. The results demonstrate the practicality and competitiveness of STT-based dynamic forests, highlighting their simpler rotation primitive and potential advantages in unrooted settings, with open questions around further optimizations and real-world applications.

Abstract

A dynamic forest data structure maintains a forest (and associated data like edge weights) under edge insertions and deletions. Dynamic forests are widely used to solve online and offline graph problems. Well-known examples of dynamic forest data structures are link-cut trees [Sleator and Tarjan '83] and top trees [Alstrup, Holm, de Lichtenberg, and Thorup '05], both of which need O(log n) time per operation. While top trees are more flexible and arguably easier to use, link-cut trees are faster in practice [Tarjan and Werneck '10]. In this paper, we propose an alternative to link-cut trees. Our data structure is based on search trees on trees (STTs, also known as elimination trees) and an STT algorithm [Berendsohn and Kozma '22] based on the classical Splay trees [Sleator and Tarjan '85]. While link-cut trees maintain a hierarchy of binary search trees, we maintain a single STT. Most of the complexity of our data structure lies in the implementation of the STT rotation primitive, which can easily be reused, simplifying the development of new STT-based approaches. We implement several variants of our data structure in the Rust programming language, along with an implementation of link-cut trees for comparison. Experimental evaluation suggests that our algorithms are faster when the dynamic forest is unrooted, while link-cut trees are faster for rooted dynamic forests.
Paper Structure (43 sections, 13 theorems, 2 equations, 11 figures, 6 tables)

This paper contains 43 sections, 13 theorems, 2 equations, 11 figures, 6 tables.

Key Result

Lemma 2.2

Let $v$ be a node in a 2-cut search tree $T$ on a tree $G$. Let $p$ be the parent of $v$ and let $a \in \partial(T_p)$. Then $v, p, a$ must lie on a common path in $G$ (though not necessarily in that order).

Figures (11)

  • Figure 1: An STT rotation (left) and the relevant parts of the underlying tree (right).
  • Figure 2: Pseudocode for $\Call{Link}{}$ and $\Call{Cut}{}$.
  • Figure 3: The MoveToRootTT implementation of NodeToRoot.
  • Figure 4: The $\mathtt{splay\_step}$ procedure.
  • Figure 5: Sketches of the two cases in a $\mathtt{splay\_step}(v)$, including the behavior of all possible types of children of $v$. A small "s" (resp. "d", "i") indicates an edge to a separator (resp. direct/indirect separator) child, and "$\neg\mathrm{s}$" (resp. "$\neg\mathrm{d}$", "$\neg\mathrm{i}$") indicates the child cannot have the respective property.
  • ...and 6 more figures

Theorems & Definitions (23)

  • Lemma 2.2
  • proof
  • Lemma 3.1
  • proof
  • Lemma 3.2
  • Lemma 6.0
  • proof
  • Lemma 6.1
  • proof
  • Lemma 6.2
  • ...and 13 more