mirror of
https://github.com/AdrianKuta/Tree-Data-Structure.git
synced 2026-01-01 04:34:55 +01:00
5: Implement post-order traversal algorithm (#16)
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
package com.github.adriankuta
|
||||
|
||||
import com.github.adriankuta.iterators.PostOrderTreeIterator
|
||||
import com.github.adriankuta.iterators.PreOrderTreeIterator
|
||||
import com.github.adriankuta.iterators.TreeNodeIterators
|
||||
import com.github.adriankuta.iterators.TreeNodeIterators.*
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationInterface<T> {
|
||||
@@ -18,6 +22,8 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn
|
||||
val children: List<TreeNode<T>>
|
||||
get() = _children
|
||||
|
||||
var defaultIterator: TreeNodeIterators = PreOrder
|
||||
|
||||
/**
|
||||
* Add new child to current node or root.
|
||||
*
|
||||
@@ -139,5 +145,8 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn
|
||||
* Output: 1 2 5 10 6 11 12 13 3 4 7 8 9
|
||||
* ```
|
||||
*/
|
||||
override fun iterator(): Iterator<TreeNode<T>> = PreOrderTreeIterator(this)
|
||||
override fun iterator(): Iterator<TreeNode<T>> = when (defaultIterator) {
|
||||
PreOrder -> PreOrderTreeIterator(this)
|
||||
PostOrder -> PostOrderTreeIterator(this)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.adriankuta
|
||||
|
||||
import com.github.adriankuta.iterators.TreeNodeIterators
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
typealias ChildDeclaration<T> = ChildDeclarationInterface<T>.() -> Unit
|
||||
@@ -13,8 +14,13 @@ typealias ChildDeclaration<T> = ChildDeclarationInterface<T>.() -> Unit
|
||||
* @see [ChildDeclarationInterface.child]
|
||||
*/
|
||||
@JvmSynthetic
|
||||
inline fun<reified T> tree(root: T, childDeclaration: ChildDeclaration<T>): TreeNode<T> {
|
||||
inline fun <reified T> tree(
|
||||
root: T,
|
||||
defaultIterator: TreeNodeIterators = TreeNodeIterators.PreOrder,
|
||||
childDeclaration: ChildDeclaration<T>
|
||||
): TreeNode<T> {
|
||||
val treeNode = TreeNode(root)
|
||||
treeNode.defaultIterator = defaultIterator
|
||||
treeNode.childDeclaration()
|
||||
return treeNode
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.github.adriankuta.iterators
|
||||
|
||||
import com.github.adriankuta.TreeNode
|
||||
|
||||
/**
|
||||
* Tree is iterated by using `Post-order Traversal Algorithm"
|
||||
* 1. Check if the current node is empty or null.
|
||||
* 2. Display the data part of the root (or current node).
|
||||
* 3. Traverse the left subtree by recursively calling the pre-order function.
|
||||
* 4. Traverse the right subtree by recursively calling the pre-order function.
|
||||
* ```
|
||||
* E.g.
|
||||
* 1
|
||||
* / | \
|
||||
* / | \
|
||||
* 2 3 4
|
||||
* / \ / | \
|
||||
* 5 6 7 8 9
|
||||
* / / | \
|
||||
* 10 11 12 13
|
||||
*
|
||||
* Output: 1 2 5 10 6 11 12 13 3 4 7 8 9
|
||||
* ```
|
||||
*/
|
||||
class PostOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
|
||||
private val stack = ArrayDeque<TreeNode<T>>()
|
||||
|
||||
init {
|
||||
stack.addAll(getChildrenStack(root))
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = stack.isNotEmpty()
|
||||
|
||||
override fun next(): TreeNode<T> {
|
||||
return stack.removeFirst()
|
||||
}
|
||||
|
||||
private fun getChildrenStack(node: TreeNode<T>): ArrayDeque<TreeNode<T>> {
|
||||
val stack = ArrayDeque<TreeNode<T>>()
|
||||
if(node.children.isEmpty()) {
|
||||
return ArrayDeque(listOf(node))
|
||||
}
|
||||
node.children.forEach {
|
||||
stack.addAll(getChildrenStack(it))
|
||||
}
|
||||
stack.addLast(node)
|
||||
return stack
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
package com.github.adriankuta
|
||||
package com.github.adriankuta.iterators
|
||||
|
||||
import com.github.adriankuta.TreeNode
|
||||
|
||||
/**
|
||||
* Tree is iterated by using `Pre-order Traversal Algorithm"
|
||||
@@ -31,10 +33,12 @@ class PreOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> {
|
||||
override fun hasNext(): Boolean = stack.isNotEmpty()
|
||||
|
||||
override fun next(): TreeNode<T> {
|
||||
println(stack)
|
||||
val node = stack.removeLast()
|
||||
node.children
|
||||
.asReversed()
|
||||
.forEach { stack.addLast(it) }
|
||||
println(stack)
|
||||
return node
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.github.adriankuta.iterators
|
||||
|
||||
enum class TreeNodeIterators {
|
||||
PreOrder, PostOrder
|
||||
}
|
||||
Reference in New Issue
Block a user