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=[])])])
相關文章
相關標籤/搜索