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

引言

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

/**
 *  设计一个多叉树的序列化与反序列化算法。
 *
 *  <p>
 *  多叉树的每一个节点最多拥有100个子节点,每一个节点有一个 Int 类型字段 value。
 *
 *  例如:
 *          [1]
 *         /   \
 *       [2]   [4]
 *      / | \    \
 *    [1][9][8]  [3]
 *
 * </p>
 *
 *  请使用 MyTree 结构做为多叉树定义 。
 */

N叉树

咱们这里就直说N叉树了,其每一个节点最多拥有N个子节点。序列化/反序列化算法的工做方式没有任何限制。咱们只须要确保将N元树能够序列化为字符串,而且能够将该字符串反序列化为原始树结构便可。面试

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

上代码:app

fun main(args: Array<String>) {
    //
    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<TreeNode> = 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<String> = LinkedList()
    // 添加数据
    for (item in arr) {
        queue.add(item)
    }
    return order(queue)!!
}

/**
 * 使用队列遍历
 *
 */
fun order(queue: Queue<String>): TreeNode? {
    // 移除并返问队列头部的元素 也就是去掉以前添加的长度值
    val cur = queue.poll()
    println("cur=$cur")
    if ("#" == cur) return null
    val nodes: MutableList<TreeNode> = 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)
}

序列化后:ui

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=[])])])
相关文章
相关标签/搜索