mirror of
https://github.com/AdrianKuta/Tree-Data-Structure.git
synced 2026-06-20 03:10:14 +02:00
feat!: v4.0 breaking API cleanup + explicitApi
BREAKING changes to the core: - treeIterator is now a read-only `val`; added `iterator(order)` and use `asSequence(order)`. - removeChild() only removes a direct child of the receiver; added `detach()` to unhook a node. - addChild() rejects re-parenting and cycles (throws TreeNodeException); detach() first to move. - clear() no longer nulls the receiver's own parent; only removes descendants. - path() returns List<TreeNode<T>>? (null) instead of throwing. Also: - Enable strict explicitApi() across core + both modules; add explicit `public` modifiers. - Update tests for the new contracts + add TreeNodeV4Test; refresh .api baselines. - README + CHANGELOG (with migration notes); bump version to 4.0.0. 47 JVM tests green.
This commit is contained in:
@@ -2,7 +2,7 @@ package com.github.adriankuta.datastructure.tree
|
||||
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
interface ChildDeclarationInterface<T> {
|
||||
public interface ChildDeclarationInterface<T> {
|
||||
|
||||
/**
|
||||
* This method is used to easily create child in node.
|
||||
@@ -20,5 +20,5 @@ interface ChildDeclarationInterface<T> {
|
||||
* @return New created TreeNode.
|
||||
*/
|
||||
@JvmSynthetic
|
||||
fun child(value: T, childDeclaration: ChildDeclaration<T>? = null): TreeNode<T>
|
||||
public fun child(value: T, childDeclaration: ChildDeclaration<T>? = null): TreeNode<T>
|
||||
}
|
||||
@@ -27,14 +27,14 @@ import kotlin.jvm.JvmSynthetic
|
||||
* @param treeIterator the default traversal order used by [iterator]. Prefer the
|
||||
* `asSequence(order)` / `preOrderSequence()` extensions to choose an order without mutating state.
|
||||
*/
|
||||
open class TreeNode<T>(val value: T, var treeIterator: TreeNodeIterators = PreOrder) : Iterable<TreeNode<T>>, ChildDeclarationInterface<T> {
|
||||
public open class TreeNode<T>(public val value: T, public val treeIterator: TreeNodeIterators = PreOrder) : Iterable<TreeNode<T>>, ChildDeclarationInterface<T> {
|
||||
|
||||
private var _parent: TreeNode<T>? = null
|
||||
|
||||
/**
|
||||
* The converse notion of a child, an immediate ancestor.
|
||||
*/
|
||||
val parent: TreeNode<T>?
|
||||
public val parent: TreeNode<T>?
|
||||
get() = _parent
|
||||
|
||||
private val _children = mutableListOf<TreeNode<T>>()
|
||||
@@ -42,28 +42,53 @@ open class TreeNode<T>(val value: T, var treeIterator: TreeNodeIterators = PreOr
|
||||
/**
|
||||
* A group of nodes with the same parent.
|
||||
*/
|
||||
val children: List<TreeNode<T>>
|
||||
public val children: List<TreeNode<T>>
|
||||
get() = _children
|
||||
|
||||
/**
|
||||
* Checks whether the current tree node is the root of the tree
|
||||
* @return `true` if the current tree node is root of the tree, `false` otherwise.
|
||||
*/
|
||||
val isRoot: Boolean
|
||||
public val isRoot: Boolean
|
||||
get() = _parent == null
|
||||
|
||||
/**
|
||||
* Add new child to current node or root.
|
||||
* Adds [child] as a direct child of this node.
|
||||
*
|
||||
* @param child A node which will be directly connected to current node.
|
||||
* @param child a node that is not already attached to a tree. To move a node that already has a
|
||||
* parent, call [detach] on it first.
|
||||
* @throws TreeNodeException if [child] already has a parent, or if attaching it here would create
|
||||
* a cycle (i.e. [child] is this node or one of its ancestors).
|
||||
*/
|
||||
fun addChild(child: TreeNode<T>) {
|
||||
public fun addChild(child: TreeNode<T>) {
|
||||
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.")
|
||||
}
|
||||
ancestor = ancestor._parent
|
||||
}
|
||||
child._parent = this
|
||||
_children.add(child)
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches this node from its parent, removing it from the parent's [children].
|
||||
*
|
||||
* @return `true` if this node was attached and is now detached; `false` if it was already a root.
|
||||
*/
|
||||
public fun detach(): Boolean {
|
||||
val currentParent = _parent ?: return false
|
||||
currentParent._children.remove(this)
|
||||
_parent = null
|
||||
return true
|
||||
}
|
||||
|
||||
@JvmSynthetic
|
||||
override fun child(value: T, childDeclaration: ChildDeclaration<T>?): TreeNode<T> {
|
||||
public override fun child(value: T, childDeclaration: ChildDeclaration<T>?): TreeNode<T> {
|
||||
val newChild = TreeNode(value)
|
||||
newChild._parent = this
|
||||
if (childDeclaration != null)
|
||||
@@ -73,21 +98,24 @@ open class TreeNode<T>(val value: T, var treeIterator: TreeNodeIterators = PreOr
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single instance of the specified node from this tree, if it is present.
|
||||
* Removes [child] from this node's direct [children], if present.
|
||||
*
|
||||
* @return `true` if the node has been successfully removed; `false` if it was not present in the tree.
|
||||
* This only removes a *direct* child of the receiver; it does not reach into other nodes. To
|
||||
* remove a node from wherever it currently lives, call [detach] on it instead.
|
||||
*
|
||||
* @return `true` if [child] was a direct child and has been removed; `false` otherwise.
|
||||
*/
|
||||
fun removeChild(child: TreeNode<T>): Boolean {
|
||||
val removed = child._parent?._children?.remove(child)
|
||||
child._parent = null
|
||||
return removed ?: false
|
||||
public fun removeChild(child: TreeNode<T>): Boolean {
|
||||
val removed = _children.remove(child)
|
||||
if (removed) child._parent = null
|
||||
return removed
|
||||
}
|
||||
|
||||
/**
|
||||
* This function go through tree and counts children. Root element is not counted.
|
||||
* @return All child and nested child count.
|
||||
*/
|
||||
fun nodeCount(): Int {
|
||||
public fun nodeCount(): Int {
|
||||
var count = 0
|
||||
val stack = ArrayDeque<TreeNode<T>>()
|
||||
stack.addAll(_children)
|
||||
@@ -102,7 +130,7 @@ open class TreeNode<T>(val value: T, var treeIterator: TreeNodeIterators = PreOr
|
||||
/**
|
||||
* @return The number of edges on the longest path between current node and a descendant leaf.
|
||||
*/
|
||||
fun height(): Int {
|
||||
public fun height(): Int {
|
||||
var maxDepth = 0
|
||||
val stack = ArrayDeque<Pair<TreeNode<T>, Int>>()
|
||||
stack.addLast(this to 0)
|
||||
@@ -118,7 +146,7 @@ open class TreeNode<T>(val value: T, var treeIterator: TreeNodeIterators = PreOr
|
||||
* Distance is the number of edges along the shortest path between two nodes.
|
||||
* @return The distance between current node and the root.
|
||||
*/
|
||||
fun depth(): Int {
|
||||
public fun depth(): Int {
|
||||
var depth = 0
|
||||
var tempParent = parent
|
||||
|
||||
@@ -130,53 +158,52 @@ open class TreeNode<T>(val value: T, var treeIterator: TreeNodeIterators = PreOr
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collection of nodes, which connect the current node
|
||||
* with its descendants
|
||||
* Returns the chain of nodes from [descendant] up to and including this node, or `null` if
|
||||
* [descendant] is not a strict descendant of this node.
|
||||
*
|
||||
* @param descendant the bottom child node for which the path is calculated
|
||||
* @return collection of nodes, which connect the current node with its descendants
|
||||
* @throws TreeNodeException exception that may be thrown in case if the
|
||||
* current node does not have such descendant or if the
|
||||
* specified tree node is root
|
||||
* @param descendant the node to walk up from.
|
||||
* @return the path `[descendant, …, this]`, or `null` if [descendant] is the root or is not
|
||||
* located in this node's subtree.
|
||||
*/
|
||||
@Throws(TreeNodeException::class)
|
||||
fun path(descendant: TreeNode<T>): List<TreeNode<T>> {
|
||||
|
||||
public fun path(descendant: TreeNode<T>): List<TreeNode<T>>? {
|
||||
if (descendant.isRoot) return null
|
||||
val path = mutableListOf<TreeNode<T>>()
|
||||
var node = descendant
|
||||
path.add(node)
|
||||
while (!node.isRoot) {
|
||||
node = node.parent!!
|
||||
path.add(node)
|
||||
if (node == this)
|
||||
return path
|
||||
if (node == this) return path
|
||||
}
|
||||
throw TreeNodeException("The specified tree node $descendant is not the descendant of tree node $this")
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all children from root and every node in tree.
|
||||
* Removes every descendant of this node. Afterwards [children] is empty and all former
|
||||
* descendants are detached (their parent is `null`). This node itself stays attached to its own
|
||||
* parent.
|
||||
*/
|
||||
fun clear() {
|
||||
val all = ArrayDeque<TreeNode<T>>()
|
||||
public fun clear() {
|
||||
val descendants = ArrayDeque<TreeNode<T>>()
|
||||
val stack = ArrayDeque<TreeNode<T>>()
|
||||
stack.addLast(this)
|
||||
stack.addAll(_children)
|
||||
while (stack.isNotEmpty()) {
|
||||
val node = stack.removeLast()
|
||||
all.addLast(node)
|
||||
descendants.addLast(node)
|
||||
stack.addAll(node._children)
|
||||
}
|
||||
all.forEach { node ->
|
||||
descendants.forEach { node ->
|
||||
node._parent = null
|
||||
node._children.clear()
|
||||
}
|
||||
_children.clear()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
public override fun toString(): String {
|
||||
return value.toString()
|
||||
}
|
||||
|
||||
fun prettyString(): String {
|
||||
public fun prettyString(): String {
|
||||
val stringBuilder = StringBuilder()
|
||||
print(stringBuilder, "", "")
|
||||
return stringBuilder.toString()
|
||||
@@ -198,9 +225,14 @@ open class TreeNode<T>(val value: T, var treeIterator: TreeNodeIterators = PreOr
|
||||
}
|
||||
|
||||
/**
|
||||
* You can change default iterator by changing [treeIterator] property.
|
||||
* Returns an iterator over this node and its descendants using the default [treeIterator] order.
|
||||
* Use [iterator] with an explicit order, or the `asSequence(order)` extension, to traverse in a
|
||||
* different order without changing this node's default.
|
||||
*/
|
||||
override fun iterator(): Iterator<TreeNode<T>> = when (treeIterator) {
|
||||
public override fun iterator(): Iterator<TreeNode<T>> = iterator(treeIterator)
|
||||
|
||||
/** Returns an iterator over this node and its descendants in the given [order]. */
|
||||
public fun iterator(order: TreeNodeIterators): Iterator<TreeNode<T>> = when (order) {
|
||||
PreOrder -> PreOrderTreeIterator(this)
|
||||
PostOrder -> PostOrderTreeIterator(this)
|
||||
LevelOrder -> LevelOrderTreeIterator(this)
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.github.adriankuta.datastructure.tree
|
||||
import com.github.adriankuta.datastructure.tree.iterators.TreeNodeIterators
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
typealias ChildDeclaration<T> = ChildDeclarationInterface<T>.() -> Unit
|
||||
public typealias ChildDeclaration<T> = ChildDeclarationInterface<T>.() -> Unit
|
||||
|
||||
/**
|
||||
* This method can be used to initialize new tree.
|
||||
@@ -14,7 +14,7 @@ typealias ChildDeclaration<T> = ChildDeclarationInterface<T>.() -> Unit
|
||||
* @see [ChildDeclarationInterface.child]
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline fun <reified T> tree(
|
||||
public inline fun <reified T> tree(
|
||||
root: T,
|
||||
defaultIterator: TreeNodeIterators = TreeNodeIterators.PreOrder,
|
||||
childDeclaration: ChildDeclaration<T>
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
package com.github.adriankuta.datastructure.tree
|
||||
|
||||
/** Returns the first node (pre-order) whose value matches [predicate], or `null`. Short-circuits. */
|
||||
fun <T> TreeNode<T>.findNode(predicate: (T) -> Boolean): TreeNode<T>? =
|
||||
public fun <T> TreeNode<T>.findNode(predicate: (T) -> Boolean): TreeNode<T>? =
|
||||
preOrderSequence().firstOrNull { predicate(it.value) }
|
||||
|
||||
/** All nodes (pre-order) whose value matches [predicate]. */
|
||||
fun <T> TreeNode<T>.filterNodes(predicate: (T) -> Boolean): List<TreeNode<T>> =
|
||||
public fun <T> TreeNode<T>.filterNodes(predicate: (T) -> Boolean): List<TreeNode<T>> =
|
||||
preOrderSequence().filter { predicate(it.value) }.toList()
|
||||
|
||||
/** `true` if any node's value matches [predicate]. Short-circuits. */
|
||||
fun <T> TreeNode<T>.anyNode(predicate: (T) -> Boolean): Boolean =
|
||||
public fun <T> TreeNode<T>.anyNode(predicate: (T) -> Boolean): Boolean =
|
||||
preOrderSequence().any { predicate(it.value) }
|
||||
|
||||
/** `true` if every node's value matches [predicate]. Short-circuits. */
|
||||
fun <T> TreeNode<T>.allNodes(predicate: (T) -> Boolean): Boolean =
|
||||
public fun <T> TreeNode<T>.allNodes(predicate: (T) -> Boolean): Boolean =
|
||||
preOrderSequence().all { predicate(it.value) }
|
||||
|
||||
/** Counts nodes whose value matches [predicate]. */
|
||||
fun <T> TreeNode<T>.countNodes(predicate: (T) -> Boolean): Int =
|
||||
public fun <T> TreeNode<T>.countNodes(predicate: (T) -> Boolean): Int =
|
||||
preOrderSequence().count { predicate(it.value) }
|
||||
|
||||
/** Folds [operation] over all nodes in pre-order, starting from [initial]. */
|
||||
fun <T, R> TreeNode<T>.foldNodes(initial: R, operation: (acc: R, node: TreeNode<T>) -> R): R =
|
||||
public fun <T, R> TreeNode<T>.foldNodes(initial: R, operation: (acc: R, node: TreeNode<T>) -> R): R =
|
||||
preOrderSequence().fold(initial) { acc, node -> operation(acc, node) }
|
||||
|
||||
/**
|
||||
* Returns a new tree with the same shape whose values are produced by [transform]. The original is
|
||||
* left untouched. Stack-safe (iterative), so it handles arbitrarily deep trees.
|
||||
*/
|
||||
fun <T, R> TreeNode<T>.mapValues(transform: (T) -> R): TreeNode<R> {
|
||||
public fun <T, R> TreeNode<T>.mapValues(transform: (T) -> R): TreeNode<R> {
|
||||
val newRoot = TreeNode(transform(value), treeIterator)
|
||||
val stack = ArrayDeque<Pair<TreeNode<T>, TreeNode<R>>>()
|
||||
stack.addLast(this to newRoot)
|
||||
@@ -44,13 +44,13 @@ fun <T, R> TreeNode<T>.mapValues(transform: (T) -> R): TreeNode<R> {
|
||||
}
|
||||
|
||||
/** Returns an independent deep copy of this subtree (same values, same shape, new nodes). */
|
||||
fun <T> TreeNode<T>.deepCopy(): TreeNode<T> = mapValues { it }
|
||||
public fun <T> TreeNode<T>.deepCopy(): TreeNode<T> = mapValues { it }
|
||||
|
||||
/**
|
||||
* Structural equality: `true` when [other] holds the same values in the same shape. Unlike
|
||||
* [TreeNode]'s reference equality, this compares the entire subtree. Stack-safe.
|
||||
*/
|
||||
fun <T> TreeNode<T>.structurallyEquals(other: TreeNode<T>): Boolean {
|
||||
public fun <T> TreeNode<T>.structurallyEquals(other: TreeNode<T>): Boolean {
|
||||
val stack = ArrayDeque<Pair<TreeNode<T>, TreeNode<T>>>()
|
||||
stack.addLast(this to other)
|
||||
while (stack.isNotEmpty()) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.github.adriankuta.datastructure.tree
|
||||
|
||||
/** `true` when this node has no children. */
|
||||
val <T> TreeNode<T>.isLeaf: Boolean get() = children.isEmpty()
|
||||
public val <T> TreeNode<T>.isLeaf: Boolean get() = children.isEmpty()
|
||||
|
||||
/** The number of direct children of this node. */
|
||||
val <T> TreeNode<T>.degree: Int get() = children.size
|
||||
public val <T> TreeNode<T>.degree: Int get() = children.size
|
||||
|
||||
/** Walks up the parent chain and returns the topmost ancestor (the tree root). */
|
||||
fun <T> TreeNode<T>.root(): TreeNode<T> {
|
||||
public fun <T> TreeNode<T>.root(): TreeNode<T> {
|
||||
var node = this
|
||||
var parent = node.parent
|
||||
while (parent != null) {
|
||||
@@ -18,7 +18,7 @@ fun <T> TreeNode<T>.root(): TreeNode<T> {
|
||||
}
|
||||
|
||||
/** The chain of ancestors from the immediate [parent] up to (and including) the root. */
|
||||
fun <T> TreeNode<T>.ancestors(): List<TreeNode<T>> {
|
||||
public fun <T> TreeNode<T>.ancestors(): List<TreeNode<T>> {
|
||||
val result = mutableListOf<TreeNode<T>>()
|
||||
var parent = this.parent
|
||||
while (parent != null) {
|
||||
@@ -29,13 +29,13 @@ fun <T> TreeNode<T>.ancestors(): List<TreeNode<T>> {
|
||||
}
|
||||
|
||||
/** The other children of this node's parent (excludes this node). Empty for the root. */
|
||||
fun <T> TreeNode<T>.siblings(): List<TreeNode<T>> =
|
||||
public fun <T> TreeNode<T>.siblings(): List<TreeNode<T>> =
|
||||
parent?.children?.filter { it !== this } ?: emptyList()
|
||||
|
||||
/** All leaf nodes in this subtree, in pre-order. */
|
||||
fun <T> TreeNode<T>.leaves(): List<TreeNode<T>> =
|
||||
public fun <T> TreeNode<T>.leaves(): List<TreeNode<T>> =
|
||||
preOrderSequence().filter { it.isLeaf }.toList()
|
||||
|
||||
/** All nodes in this subtree except this node, in pre-order. */
|
||||
fun <T> TreeNode<T>.descendants(): List<TreeNode<T>> =
|
||||
public fun <T> TreeNode<T>.descendants(): List<TreeNode<T>> =
|
||||
preOrderSequence().filter { it !== this }.toList()
|
||||
|
||||
@@ -10,7 +10,7 @@ import com.github.adriankuta.datastructure.tree.iterators.TreeNodeIterators
|
||||
* traversal up front. Pairs with the Kotlin stdlib, e.g.
|
||||
* `root.asSequence().map { it.value }.firstOrNull { it == target }`.
|
||||
*/
|
||||
fun <T> TreeNode<T>.asSequence(
|
||||
public fun <T> TreeNode<T>.asSequence(
|
||||
order: TreeNodeIterators = TreeNodeIterators.PreOrder,
|
||||
): Sequence<TreeNode<T>> {
|
||||
val self = this
|
||||
@@ -22,10 +22,10 @@ fun <T> TreeNode<T>.asSequence(
|
||||
}
|
||||
|
||||
/** Lazy pre-order traversal as a [Sequence]. */
|
||||
fun <T> TreeNode<T>.preOrderSequence(): Sequence<TreeNode<T>> = asSequence(TreeNodeIterators.PreOrder)
|
||||
public fun <T> TreeNode<T>.preOrderSequence(): Sequence<TreeNode<T>> = asSequence(TreeNodeIterators.PreOrder)
|
||||
|
||||
/** Lazy post-order traversal as a [Sequence]. */
|
||||
fun <T> TreeNode<T>.postOrderSequence(): Sequence<TreeNode<T>> = asSequence(TreeNodeIterators.PostOrder)
|
||||
public fun <T> TreeNode<T>.postOrderSequence(): Sequence<TreeNode<T>> = asSequence(TreeNodeIterators.PostOrder)
|
||||
|
||||
/** Lazy level-order (breadth-first) traversal as a [Sequence]. */
|
||||
fun <T> TreeNode<T>.levelOrderSequence(): Sequence<TreeNode<T>> = asSequence(TreeNodeIterators.LevelOrder)
|
||||
public fun <T> TreeNode<T>.levelOrderSequence(): Sequence<TreeNode<T>> = asSequence(TreeNodeIterators.LevelOrder)
|
||||
|
||||
@@ -2,5 +2,5 @@ package com.github.adriankuta.datastructure.tree.exceptions
|
||||
|
||||
import kotlin.jvm.JvmOverloads
|
||||
|
||||
class TreeNodeException @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
|
||||
public class TreeNodeException @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
|
||||
RuntimeException(message, cause)
|
||||
@@ -20,7 +20,7 @@ import com.github.adriankuta.datastructure.tree.TreeNode
|
||||
* Output: 1 2 3 4 5 6 7 8 9 10 11 12 13
|
||||
* ```
|
||||
*/
|
||||
class LevelOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
public class LevelOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
|
||||
private val stack = ArrayDeque<TreeNode<T>>()
|
||||
|
||||
@@ -28,9 +28,9 @@ class LevelOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
stack.addLast(root)
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = stack.isNotEmpty()
|
||||
public override fun hasNext(): Boolean = stack.isNotEmpty()
|
||||
|
||||
override fun next(): TreeNode<T> {
|
||||
public override fun next(): TreeNode<T> {
|
||||
val node = stack.removeFirst()
|
||||
node.children
|
||||
.forEach { stack.addLast(it) }
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.github.adriankuta.datastructure.tree.TreeNode
|
||||
* Output: 10 5 11 12 13 6 2 3 7 8 9 4 1
|
||||
* ```
|
||||
*/
|
||||
class PostOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
public class PostOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
|
||||
private val result = ArrayDeque<TreeNode<T>>()
|
||||
|
||||
@@ -37,7 +37,7 @@ class PostOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
}
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = result.isNotEmpty()
|
||||
public override fun hasNext(): Boolean = result.isNotEmpty()
|
||||
|
||||
override fun next(): TreeNode<T> = result.removeFirst()
|
||||
public override fun next(): TreeNode<T> = result.removeFirst()
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import com.github.adriankuta.datastructure.tree.TreeNode
|
||||
* Output: 1 2 5 10 6 11 12 13 3 4 7 8 9
|
||||
* ```
|
||||
*/
|
||||
class PreOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
public class PreOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
|
||||
private val stack = ArrayDeque<TreeNode<T>>()
|
||||
|
||||
@@ -28,9 +28,9 @@ class PreOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
stack.addLast(root)
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = stack.isNotEmpty()
|
||||
public override fun hasNext(): Boolean = stack.isNotEmpty()
|
||||
|
||||
override fun next(): TreeNode<T> {
|
||||
public override fun next(): TreeNode<T> {
|
||||
val node = stack.removeLast()
|
||||
node.children
|
||||
.asReversed()
|
||||
|
||||
@@ -5,7 +5,7 @@ package com.github.adriankuta.datastructure.tree.iterators
|
||||
* @see PostOrder
|
||||
* @see LevelOrder
|
||||
*/
|
||||
enum class TreeNodeIterators {
|
||||
public enum class TreeNodeIterators {
|
||||
/**
|
||||
* Tree is iterated by using `Pre-order Traversal Algorithm"
|
||||
* The pre-order traversal is a topologically sorted one,
|
||||
|
||||
Reference in New Issue
Block a user