mirror of
https://github.com/AdrianKuta/Tree-Data-Structure.git
synced 2026-06-20 03:10:14 +02:00
feat: tree-structure-compose (LazyTree) + O(n) addChild cycle check
- New published module tree-structure-compose: a LazyTree composable for Compose Multiplatform (JVM/desktop, iOS, Wasm) with lazy rendering and expand/collapse. - Fix an O(n^2) regression in addChild(): only walk ancestors for cycle detection when the child already has a subtree (a fresh leaf can never form a cycle), so building deep trees is O(n) again. Caught by the deep-chain stack-safety test on JS. - README: Compose usage section; align all install snippets to 4.0.0. - Version catalog: Compose Multiplatform + compose-compiler plugins. Verified locally: JVM, JS(node), Wasm(node), iOS-simulator tests + apiCheck all green; Compose module compiles for JVM, Wasm and iOS.
This commit is contained in:
@@ -64,12 +64,19 @@ public open class TreeNode<T>(public val value: T, public val treeIterator: Tree
|
||||
if (child._parent != null) {
|
||||
throw TreeNodeException("$child already has a parent; call detach() before re-attaching it.")
|
||||
}
|
||||
var ancestor: TreeNode<T>? = this
|
||||
while (ancestor != null) {
|
||||
if (ancestor === child) {
|
||||
throw TreeNodeException("Adding $child here would create a cycle.")
|
||||
if (child === this) {
|
||||
throw TreeNodeException("Adding $child here would create a cycle.")
|
||||
}
|
||||
// Only a node that already has its own subtree can contain `this` and thus form a cycle.
|
||||
// Skipping this walk for leaves keeps building deep trees O(n) instead of O(n²).
|
||||
if (child._children.isNotEmpty()) {
|
||||
var ancestor: TreeNode<T>? = _parent
|
||||
while (ancestor != null) {
|
||||
if (ancestor === child) {
|
||||
throw TreeNodeException("Adding $child here would create a cycle.")
|
||||
}
|
||||
ancestor = ancestor._parent
|
||||
}
|
||||
ancestor = ancestor._parent
|
||||
}
|
||||
child._parent = this
|
||||
_children.add(child)
|
||||
|
||||
Reference in New Issue
Block a user