2016-05-13 48 views
2

我花了相当一段时间思考某个问题,但我找不到满意的解决方案,它对我来说已成为一个阻塞问题。
情况如下。JavaScript嵌套树排名

我正在写管理动态树结构(没有二进制)小Javascript库,并且其中根/节点被表示为在一个JSON数组对象:

var json = [{ text: "root", children: [ 
       {id: "id_1", text: "node_1", children:[ 
        {id: "id_c1", text: "node_c1"}, 
        {id: "id_c2", text: "node_c2", children: [ 
         {id: "id_c2_c1", text: "node_c2_c1"}, 
         {id: "id_c2_c2", text: "node_c2_c2"}, 
         {id: "id_c2_c3", text: "node_c2_c3"}]}, 
        {id: "id_c3", text: "node_c3"}]}, 
       {id: "id_2", text: "node_2"}]}]; 

我有几个问题(第一个是核心,其他核心是由它产生的):

  1. 似乎不可能以直接方式(从上到下)对节点进行排名。插入/删除节点会使得排名变得糟糕。
  2. 次要的,因此,我找不到一个好的方法来实现间隔(节点数组)的检索,当给出两个节点(开始/结束)时。这在一个换档选择树形菜单上的范围:

enter image description here

  • 另一个后果是,我不能维持我的节点时的正确顺序随机选择并将它们添加到临时数组中(使用命令键 - 用于以与检索到的顺序相同的顺序拖放)。由于我无法为节点分配排名,所以我无法维持其顺序。
  • 最明显的解决方案是扁平化json数组并重新索引每个操作的所有节点(这显然有效),但我相当肯定这总体上是一个相当糟糕的想法(低效率)。

    我想出的另一个想法是根据算法(使用索引,级别等)为每个节点赋予一定的“权重”。但我无法找到一个正确的方法来计算重量。而且,它不能解决问题,因为插入/删除随机节点似乎仍然需要重建索引。

    这里是我当前的代码:https://gist.github.com/kimgysen/9d066bdf095b853c4d0e67517a76777d

    任何帮助或输入对此事将不胜感激......

    注:我不希望任何人去通过整个代码,它更我坚持的概念性编程问题。如果有的话,我对概念性解决方案感到满意。

    +0

    幻灯片我不知道你的意思究竟是什么,但你并不需要维持一个索引,你可以指望你想通过索引检索每一次。看看“深度优先预置遍历”。很明显,指数会随着插入而改变;如果你不想这样做,你就不能使用索引;您可以使用唯一的ID代替。 – Amadan

    +0

    @Amadan随着索引我的意思是按特定顺序列出节点,并根据它们从顶部的位置给出一个值,以便能够在整个树上维护任何节点的顺序与另一个节点的顺序。不知道我是否清楚。我会检查你的建议,谢谢。不知何故,我正在寻找一种重新编制索引的方法,但采用更优化的方式,而不是重新索引整个树。考虑到一棵很大的树,我不确定这会对性能产生什么影响。 – Trace

    +0

    我明白了。对于一棵非常大的树,我同意,重塑变革更有意义。尽管如此,预先遍历是以您想要的顺序访问所有节点的方式。 – Amadan

    回答

    0

    这是我的解决方案:

     [ {id: "root",  p_id: 0,  l_id: 0,   text: "website"}, 
         {id: "header", p_id: "root", l_id: 0,   text: "Parent: root, left: none"}, 
         {id: "nav",  p_id: "header", l_id: 0,   text: "Parent: header, left:none"}, 
         {id: "headline", p_id: "header", l_id: "nav",  text: "Parent: header, left: nav"}, 
         {id: "promotion", p_id: "header", l_id: "headline", text: "Parent: header, left: headline"}, 
         ]; 
    

    插入一个节点

    如果需要 '标题' 之前插入一个名为 'new_node' 新节点。

    {id: "new_node",  p_id: ,  l_id: ,   text: "Parent:header, left:nav"}, 
    
    1. 查找元素ID是 '标题'。
    2. 将其p_id和l_id复制到new_node。
    3. 将'标题'的l_id更新为'new_node'。

      {id: "headline", p_id: "header", l_id: "new_node",  text: "Parent: header, left: new_node"} 
      {id: "new_node", p_id: "header", l_id: "nav",  text: "Parent: header, left: nav"}, 
      

    删除节点

    删除 '标题'。

    1. 保存标题的l_id并删除元素。
    2. 查找所有p_id为'标题'的元素,将其删除。
    3. 找到'l_id'为'标题'的元素,将其l_id更改为标题的元素。

    该解决方案从“分层分类模型”派生,每个元素可能有孩子,和孩子可以再有孩子。除此之外,“父节点”内的每个元素都需要知道他的直接兄弟。我认为这是一个“链接列表”结构。

    这里是hierarchical categories model