N叉树的序列化与反序列化

引言

首先这是去Keep面试的一道算法题,搜了下LeetCode上也有...不过Keep稍微改了下

/**
 *  设计一个多叉树的序列化与反序列化算法。
 *
 *  

* 多叉树的每个节点最多拥有100个子节点,每个节点有一个 Int 类型字段 value。 * * 例如: * [1] * / \ * [2] [4] * / | \ \ * [1][9][8] [3] * *

* * 请使用 MyTree 结构作为多叉树定义 。 */

N叉树

我们这里就直说N叉树了,其每个节点最多拥有N个子节点。序列化/反序列化算法的工作方式没有任何限制。我们只需要确保将N元树可以序列化为字符串,并且可以将该字符串反序列化为原始树结构即可。

开始想到的就是与二叉树的序列化思路一样,用递归序列化, 反序列化的时候用一个queue表示遍历的过程。

上代码:

fun main(args: Array) {
    //
    val mList = mutableListOf(TreeNode(2), TreeNode(4))
    mList[0].nodes.addAll(0, mutableListOf(TreeNode(1), TreeNode(9), TreeNode(8)))
    mList[1].nodes.addAll(0, mutableListOf(TreeNode(3)))
    val root = TreeNode(1, mList)

    //
    val serializeMyTreeString = serializeMyTree(root)
    println(serializeMyTreeString)
    println(deserializeMyTree(serializeMyTreeString))
}

data class TreeNode(
        val value: Int,
        val nodes: MutableList = mutableListOf()
)

fun serializeMyTree(root: TreeNode): String {
    if (null == root) return "#"
    val sb = StringBuilder()
    order(root, sb)
    return sb.toString()
}

fun order(root: TreeNode, sb: StringBuilder) {
    if (root == null) {
        sb.append("#")
        return
    }
    // 将每个子节点的长度添加在后面,便于终止遍历 用String.join()也可以
    sb.append(root.value).append(",").append(root.nodes.size)
    for (node in root.nodes) {
        sb.append(",")
        // 递归
        order(node, sb)
    }
}

fun deserializeMyTree(s: String): TreeNode? {
    // 这里不用判断 s 的长度是否为0 ,因为之前用了 # 字符
    // 去掉分隔符
    val arr = s.split(",".toRegex()).toTypedArray()
    if (arr.isEmpty()) return null
    // LinkedList实现队列
    val queue: Queue = LinkedList()
    // 添加数据
    for (item in arr) {
        queue.add(item)
    }
    return order(queue)!!
}

/**
 * 使用队列遍历
 *
 */
fun order(queue: Queue): TreeNode? {
    // 移除并返问队列头部的元素 也就是去掉之前添加的长度值
    val cur = queue.poll()
    println("cur=$cur")
    if ("#" == cur) return null
    val nodes: MutableList = mutableListOf()
    // 获取头部节点的子节点数量
    val nodesSize = Integer.valueOf(queue.poll())
    // 遍历队列 注意不包含
    for (i in 0 until nodesSize) {
        // 递归
        order(queue)?.let { nodes.add(it) }
    }

    return TreeNode(Integer.valueOf(cur), nodes)
}

序列化后:

1,2,2,3,1,0,9,0,8,0,4,1,3,0

反序列化:

TreeNode(value=1, nodes=[TreeNode(value=2, nodes=[TreeNode(value=1, nodes=[]), TreeNode(value=9, nodes=[]), TreeNode(value=8, nodes=[])]), TreeNode(value=4, nodes=[TreeNode(value=3, nodes=[])])])

你可能感兴趣的:(算法-数据结构,kotlin)