【发布时间】:2020-08-24 01:54:10
【问题描述】:
如何在不递归的情况下迭代地克隆/复制 N 叉树?只需要迭代重写cloneRecursive函数:
import java.util.ArrayDeque
sealed class Row {
abstract val name: String
data class Section(override val name: String, val rows: List<Row>) : Row()
data class Field(override val name: String, val data: String) : Row()
}
fun main() {
val root = Row.Section(
"root", listOf(
Row.Section(
"section 1", listOf(
Row.Section(
"section 1.1", listOf(
Row.Field("field 1.1.1", "1.1.1 - 1"),
Row.Field("field 1.1.2", "1.1.2 - 1")
)
),
Row.Field("field 1.2", "1.2 - 1")
)
),
Row.Field("field 2", "2 - 1"),
Row.Field("field 3", "3 - 1"),
Row.Section(
"section 4", listOf(
Row.Field("field 4.1", "4.1 - 1"),
Row.Field("field 4.2", "4.2 - 1"),
Row.Section(
"section 4.3", listOf(
Row.Field("field 4.3.1", "4.3.1 - 1"),
Row.Field("field 4.3.2", "4.3.2 - 1")
)
)
)
)
)
)
println(root)
println(recursiveClone(root))
println(root == recursiveClone(root))
}
fun recursiveClone(root: Row): Row {
return when (root) {
is Row.Section -> {
val rows = root.rows.map { row ->
recursiveClone(row)
}
Row.Section(root.name, rows)
}
is Row.Field -> {
Row.Field(root.name, root.data)
}
}
}
【问题讨论】:
-
你能解释一下背景和动机吗?这是一个具有挑战性的问题,但也有点毫无意义,因为您使用的是纯粹不可变的类和属性。可以修改类吗?
-
@Tenfour04 我只需要基于源码树进行转换。例如,将分层 JSON 反序列化为树对象。克隆只是这种转变的一个简单例子。这就是重点——我想要迭代算法来制作深度不可变的树克隆。为了处理不变性需要使用后序遍历进行克隆,其中根节点是最后一个访问节点。
-
这个问题似乎是合理的,我认为它并没有太大的挑战性(您可以使用显式堆栈而不是隐式调用堆栈)。你会接受 Java 的答案吗?我不熟悉 Kotlin。
-
@ggorlen 当然。 Java 是一个很好的变体 :)
-
@ggorlen “挑战”是相对的——这绝对是可能的。我有兴趣看到解决方案以及它们的简洁或清晰程度。我开始尝试用堆栈来做,但发现要按照我的方式做需要不止一个集合。
标签: java kotlin recursion data-structures tree