树的自定义遍历逻辑

时间:2018-11-29 21:20:58

标签: swift

我有一个平面列表,可以使用此代码将其转换为树

class Node {
    var Children: [Node] = []
    weak var parent: Node?
    weak var nextObject: Node?
    var associatedObject: AppListItem?

    init(associatedObject: AppListItem) {
        self.associatedObject = associatedObject
    }
}

func getRootsFrom(list: [AppListItem]) -> [Node] {
    var dict: [String : Node] = [:]
    list.forEach { (appItem) in
        dict[appItem.uuid] = Node(associatedObject: appItem)
    }
    dict.values.forEach { (node) in
        var proposedParent: Node
        if let value = dict[node.associatedObject?.parentUUID ?? ""] {
            proposedParent = value
            node.parent = proposedParent
            proposedParent.Children.append(node)
            proposedParent.Children.sort(by: {$0.associatedObject?.sort ?? "" < $1.associatedObject?.sort ?? ""})
            proposedParent.nextObject = proposedParent.Children.first
        }
    }
    return dict.values.filter({$0.parent == nil}).sorted(by: {$0.associatedObject?.sort ?? "" < $1.associatedObject?.sort ?? ""})
}

其中getRootsFrom将列表转换为树,并返回根,我在正确标记每个对象的nextObject时遇到问题。

enter image description here

所以下一个对象应该是

  

饮料->感冒->牛奶->苏打水->苦柠檬->姜汁

,然后应该转到

  

热门

等等...

我不太确定我的代码是否正确执行,它仅在第一个叶子之前和下一个nextObject变为nil时才标记

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

看起来您已经在构建树,因此将其纳入列表应该相当简单。根据您的图像,您似乎想使用pre order traversal获得一个数组。首先,我将填充方法添加到Node

func preorder() -> [Node] {
    return [self] + Children.flatMap { $0.preorder() }
}

然后在getRootsFrom中将返回值更改为

return dict.values.first(where: {$0.parent == nil})?.preorder() ?? []

wikipedia article on tree traversal是阅读有关此内容的重要资料。它使用图像和伪代码显示不同的顺序。