2017-04-07 42 views
3

我一直在使用下面的代码:http://bl.ocks.org/NPashaP/7683252。这是一棵树的图形表示。我剥去了大部分代码(优雅标签),每个父代只允许两个节点,并将数据结构更改为一个数组。如何动态地重新定位二叉树节点

现在剩下的唯一问题是重新定位。原始代码完美无缺。但是因为我想要一个二叉树,所以我让用户选择插入一个左侧或右侧的孩子。原始的重新定位代码将第一个孩子直接从父代中移除,但是在二叉树中这是错误的。我希望它能够左转或右转。

reposition = function (v) { 
    function repos(v) { 
     var lC = getLeafCount(v.v), 
      left = v.p.x; //parent's x-position 

     v.c.forEach(function (d) { 
      var vc = d; //saving reference of the child in parent object 
      d = tree.getVerticeById(d.v); //actually fetching the child object 
      var w = 0; 
      if(d.d == 'right') { w += 15 * lC } 
      if(d.d == 'left') { w -= 15 * lC } 
      d.p = {x: left + w, y: v.p.y + tree.h}; //setting the position 
      vc.p = d.p; //setting the child's pos in parent obj 
      repos(d); 
     }); 
    } 
    repos(v[0]); 
}; 

我的代码的一些部分与原始代码不同,因为我已经改变了前面所述的数据结构。我试图评论可能令人困惑的部分,但重要的是重新定位的数学。

起初,这段代码看起来效果不错(https://i.stack.imgur.com/gjzOq.png)。但经过一些测试后,我发现重新定位存在一个巨大的问题:节点彼此崩溃(https://i.stack.imgur.com/pdQfy.png)!

结论:我试图修改原始功能,以记住节点的左右位置,但无法做到这一点。我写了这种方法的变体,但它仍然有一些问题,如图片中所示。我会感谢在这个问题上的一些意见。

回答

0

我最终为此问题做了一个快速修复。

运行问题中发布的重定位函数后,我运行了另一个解决问题的函数。新函数遍历树的所有级别并检查节点是否靠得太近。如果是,则该算法找到最接近的共同祖先,并且增加其左侧和右侧儿童之间的距离。在此之后,节点之间不再有碰撞。