查找层次结构中最长链的长度

时间:2018-02-07 21:56:57

标签: javascript d3.js hierarchy

我有分层数据用于在我的应用程序中创建一个svg。我需要找到该数据源中最长链的长度。我可以逐层浏览数据源,递归深入读取_children,调用递归函数来计算级别,但我确信必须有更好的方法。这更加复杂,因为数据源可以从它以_children和_parents开始的节点向两个方向发送。

var findChildren = function (ds, level) {
    if (!ds._children || ds._children.length == 0) {
        return level;
    }

    var longest = level + 1;
    ds._children.forEach(function (item) {
        var result = findChildren(item, level + 1);
        if (result > longest) {
            longest = result;
        }
    });
    return longest;
}

这是我目前正在使用的函数,它具有相同的功能,可以检查ds._parents以另一种方式,将一个结果作为另一个的起始级别传递。我确信必须有更好的方法...

例如,相同的数据可以有三种方式,具体取决于用户打开树的位置。

  1. {"number":1,"type":"Delivery","_parents":[{"number":1,"type":"Order","_parents":[{"number":1,"type":"Quote"}]}]}

  2. {"number":1,"type":"Order","_parents":[{"number":1,"type":"Quote"}], "_children":[{"number":1,"type":"Delivery"}]}

  3. {"number":1,"type":"Quote","_children":[{"number":1,"type":"Order","_children":[{"number":1,"type":"Delivery"}]}]}

1 个答案:

答案 0 :(得分:2)

你说你......

  

需要找到该数据源中最长链的长度。

这是数据结构中根到最深叶子的长度。有方便的D3方法可以快速找到最深的叶子。

所以,假设我们有一个像this这样的分层数据:

{
    "name": "Eve",
    "children": [{
        "name": "Cain"
    }, {
        "name": "Seth",
        "children": [{
            "name": "Enos"
        }, {
            "name": "Noam"
        }]
    }, {
        "name": "Abel"
    }, {
        "name": "Awan",
        "children": [{
            "name": "Enoch"
        }]
    }, {
        "name": "Azura"
    }]
}

当您将其传递给d3.hierarchy() ...

var hierarchy = d3.hierarchy(data);

...它会在每个节点中自动创建一个名为depth的属性:

  

node.depth - 根节点为零,每个后代生成增加1。

因此,我们只需要一个简单的函数来获得最大的depth值。例如:

var longest = d3.max(hierarchy.descendants().map(function(d) {
    return d.depth
}));

这是一个演示:



var data = {
  "name": "Eve",
  "children": [{
    "name": "Cain"
  }, {
    "name": "Seth",
    "children": [{
      "name": "Enos"
    }, {
      "name": "Noam"
    }]
  }, {
    "name": "Abel"
  }, {
    "name": "Awan",
    "children": [{
      "name": "Enoch"
    }]
  }, {
    "name": "Azura"
  }]
};

var hierarchy = d3.hierarchy(data);
var longest = d3.max(hierarchy.descendants().map(function(d) {
  return d.depth
}));
console.log("The longest chain has " + (longest + 1) + " levels.")

<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;