【问题标题】:JavaScript: Quadtree comparisonJavaScript:四叉树比较
【发布时间】:2020-09-23 07:44:00
【问题描述】:

我没有找到任何快速算法来获取以下格式的四叉树差异。 假设我们有两个任意的 4 级树:

var tree1 = [

    { id: "1.1", children: [

        { id: "1.1.1", children: null },
        { id: "1.1.2", children: null },
        { id: "1.1.3", children: [

            { id: "1.1.3.1", children: null },
            { id: "1.1.3.2", children: null },
            { id: "1.1.3.3", children: null },
            { id: "1.1.3.4", children: null }

        ] },
        { id: "1.1.4", children: null }

    ] },
    { id: "1.2", children: null },
    { id: "1.3", children: [

        { id: "1.3.1", children: [

            { id: "1.3.1.1", children: null },
            { id: "1.3.1.2", children: null },
            { id: "1.3.1.3", children: null },
            { id: "1.3.1.4", children: null }

        ] },
        { id: "1.3.2", children: null },
        { id: "1.3.3", children: null },
        { id: "1.3.4", children: null }

    ] },
    { id: "1.4", children: null }

];

var tree2 = [

  { id: "1.1", children: [

        { id: "1.1.1", children: null },
        { id: "1.1.2", children: null },
        { id: "1.1.3", children: null },
        { id: "1.1.4", children: [

            { id: "1.1.4.1", children: null },
            { id: "1.1.4.2", children: null },
            { id: "1.1.4.3", children: null },
            { id: "1.1.4.4", children: null }

        ] }

  ] },
  { id: "1.2", children: [

        { id: "1.2.1", children: null },
        { id: "1.2.2", children: null },
        { id: "1.2.3", children: [

            { id: "1.2.3.1", children: null },
            { id: "1.2.3.2", children: null },
            { id: "1.2.3.3", children: null },
            { id: "1.2.3.4", children: null }

        ] },
        { id: "1.2.1", children: null }

  ]},
  { id: "1.3", children: null },
  { id: "1.4", children: [

        { id: "1.4.1", children: [

            { id: "1.4.1.1", children: null },
            { id: "1.4.1.2", children: null },
            { id: "1.4.1.3", children: null },
            { id: "1.4.1.4", children: null }

        ] },
        { id: "1.4.2", children: null },
        { id: "1.4.3", children: null },
        { id: "1.4.1", children: null }

  ] }

];

所以,我需要找到差异并将它们返回为:

var result = {

    "1.1.3.1" : "1.1.3",
    "1.1.3.2" : "1.1.3",
    "1.1.3.3" : "1.1.3",
    "1.1.3.4" : "1.1.3",
    "1.1.4" : ["1.1.4.1", "1.1.4.2", "1.1.4.3", "1.1.4.4"],
    "1.2" : ["1.2.1", "1.2.2". ["1.2.3.1", "1.2.3.2", "1.2.3.3", "1.2.3.4"], "1.2.4"],
    "1.3.1.1" : "1.3",
    "1.3.1.2" : "1.3",
    "1.3.1.3" : "1.3",
    "1.3.1.4" : "1.3",
    "1.3.2" : "1.3",
    "1.3.3" : "1.3",
    "1.3.4" : "1.3",
    "1.4" : [["1.4.1.1", "1.4.1.2", "1.4.1.3", "1.4.1.4"], "1.4.2", "1.4.3", "1.4.4"]

 };

如果可以看到,结果必须是与更新对应的地图或字典。 不知道如何将 ["1.1.3.1", "1.1.3.2", "1.1.3.3", "1.1.3.4"] 引用到单个索引,所以我将它们拆分,但是如果有更优雅的不客气。

此数据是手动创建的,如有错误请见谅。

【问题讨论】:

    标签: javascript search tree difference quadtree


    【解决方案1】:

    您可以构建一棵树,在其中添加标记 where 以添加/删除树的一部分并从中获得差异。

    function getDifference(t1, t2) {
    
        function getD(object, parent) {
            function getKeys({ where, ...object }) {
                return Object.keys(object).flatMap(k => [k, ...(object[k] ? getKeys(object[k]) : [])]);
            }
    
            var types;
    
            Object
                .entries(object)
                .forEach(([k, { where, ...o }]) => {
                    if (where) {
                        let keys = getKeys(o);
                        if (!types) types = {};
                        if (!types[where]) types[where] = [];
                        types[where].push(keys.length ? [k, keys] : k);
                    } else {
                        getD(o, k);
                    }
                });
    
            if (types) {
                if (-1 in types) result.push([types[-1], parent]);
                if (1 in types) result.push([parent, types[1]]);
            }
        }
    
        var temp = {},
            add = (inc, tree) => ({ id, children }) => {
                tree[id] = tree[id] || { where: 0 };
                tree[id].where += inc;
                if (children) children.forEach(add(inc, tree[id]));
            },
            result = [];
    
        t1.forEach(add(-1, temp));
        t2.forEach(add(1, temp));
    
        getD(temp);
    
        return result;
    }    
    
    var tree1 = [{ id: "1.1", children: [{ id: "1.1.1", children: null }, { id: "1.1.2", children: null }, { id: "1.1.3", children: [{ id: "1.1.3.1", children: null }, { id: "1.1.3.2", children: null }, { id: "1.1.3.3", children: null }, { id: "1.1.3.4", children: null }] }, { id: "1.1.4", children: null }] }, { id: "1.2", children: null }, { id: "1.3", children: [{ id: "1.3.1", children: [{ id: "1.3.1.1", children: null }, { id: "1.3.1.2", children: null }, { id: "1.3.1.3", children: null }, { id: "1.3.1.4", children: null }] }, { id: "1.3.2", children: null }, { id: "1.3.3", children: null }, { id: "1.3.4", children: null }] }, { id: "1.4", children: null }],
        tree2 = [{ id: "1.1", children: [{ id: "1.1.1", children: null }, { id: "1.1.2", children: null }, { id: "1.1.3", children: null }, { id: "1.1.4", children: [{ id: "1.1.4.1", children: null }, { id: "1.1.4.2", children: null }, { id: "1.1.4.3", children: null }, { id: "1.1.4.4", children: null }] }] }, { id: "1.2", children: [{ id: "1.2.1", children: null }, { id: "1.2.2", children: null }, { id: "1.2.3", children: [{ id: "1.2.3.1", children: null }, { id: "1.2.3.2", children: null }, { id: "1.2.3.3", children: null }, { id: "1.2.3.4", children: null }] }, { id: "1.2.4", children: null }] }, { id: "1.3", children: null }, { id: "1.4", children: [{ id: "1.4.1", children: [{ id: "1.4.1.1", children: null }, { id: "1.4.1.2", children: null }, { id: "1.4.1.3", children: null }, { id: "1.4.1.4", children: null }] }, { id: "1.4.2", children: null }, { id: "1.4.3", children: null }, { id: "1.4.4", children: null }] }],
        result = getDifference(tree1, tree2);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 暂时不知道,因为我有 1D 节点数组并试图弄清楚 [stackoverflow.com/questions/62196884/… 如何将它们转换为 2D 树而不会有太多痛苦。
    • 我不知道这个新问题。但是这个答案是怎么回事?
    • 我已经将一维数组转换成我这里的数组,但是,很确定你的代码可以完美运行。
    • 嗯,你能调整这个函数来获取对象,而不仅仅是它们的索引吗? "1.1.3" 到 {id: "1.1.3", children: null }
    • 你想只获取有变化的节点吗?嵌套部分包括在内...
    猜你喜欢
    • 1970-01-01
    • 2018-03-28
    • 2017-08-09
    • 2010-11-02
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 2014-06-14
    相关资源
    最近更新 更多