【问题标题】:Binary tree from general tree一般树的二叉树
【发布时间】:2011-12-29 03:41:51
【问题描述】:

我有一个树结构,它有一个带有父 ID 的节点(无限的子节点)。出于显示目的,我需要将此树结构作为二叉树。我如何做到这一点是在每个级别节点根据条件分组为单个节点。当一个节点被选中时,它的子节点就会显示出来。示例:

绿色是条件是true,红色是false

B、C 已分到左侧节点,D、E 根据条件分在右侧。

问题:我正在使用 KnockoutJS 来显示我的树,我需要能够执行正常的树操作,例如根据其 ID 获取节点、插入节点、删除节点)。这是我的结构。有没有更好的结构/方式来做到这一点?

var tree = [
    { groupNodeId: "A", childNodes: [
        { nodeId: "A", childGroupNodes: [
            { groupNodeId: "B", condition: true, childNodes: [
                { nodeId: "B", childGroupNodes: []},
                { nodeId: "C", childGroupNodes: []}
            ]},
            { groupNodeId: "D", condition: false, childNodes: [
                { nodeId: "D", childGroupNodes: []},
                { nodeId: "E", childGroupNodes: []}
            ]}
        ]}
    ]}
];

【问题讨论】:

  • 为什么插入节点使用childGroupNodesgroupNodeId,而不是继续使用childNodesnodeId?此外,例如,如果 B 和 C 各有一个子节点,其 condition 为真,您是否希望将这两个节点组合在一起?
  • 另外,我认为 groupNode 中的 condition: true D 是错字?

标签: javascript tree binary-tree knockout.js


【解决方案1】:

我不确定你到底想要什么,但假设:

  1. 您想插入“groupNodes”,而不是常规节点,并且 groupNodes 可以有无限的子节点。
  2. 原始树只包含常规节点,不包含 groupNodes。
  3. 所有常规节点都有一个 nodeId、一个设置为 true 或 false 的条件以及一个数组 childNodes。
  4. 您不想创建没有子节点的 groupNodes。

那么这就是你的答案。

function binize(tree) {
  var left,right,t,u,
    stack=[tree];
  while(t=stack.pop()) {
    left=[];
    right=[];
    while(u=t.childNodes.pop()) {
      (u.condition?left:right).push(u);
      stack.push(u);
    }
    left.length&&t.childNodes.push({
      groupNodeId:left[0].nodeId,
      condition:true,
      childNodes:left
    });
    right.length&&t.childNodes.push({
      groupNodeId:right[0].nodeId,
      condition:false,
      childNodes:right
    });
  }
}

我使用这个数据结构对其进行了测试(注意树是顶级对象,而不是包含它的数组)。

var tree={nodeId:'A',childNodes:[
  {nodeId:'B',condition:true,childNodes:[]},
  {nodeId:'C',condition:true,childNodes:[]},
  {nodeId:'D',condition:false,childNodes:[
    {nodeId:'F',condition:false,childNodes:[]},
    {nodeIf:'G',condition:false,childNodes:[]}
  ]},
  {nodeId:'E',condition:false,childNodes:[]}
]};

如果我对你的树有更多了解,那么我可能会采取不同的方法。例如,如果树不是很深,那么递归地挖掘它可能会更有效(当然也更干净)。

另外,我以前从未使用过 KnockoutJS,也不知道它喜欢什么结构。我刚刚生成了您指定的结构;希望这会奏效。

【讨论】:

  • 嗯,我今晚会测试一下,但根据我的理解,现在这可能是一个嵌套集合?或者每个节点都包含另一个二叉树的二叉树
  • 嗯,它交替模式,就像你的例子一样。所以第一层有顶层节点,下一层是两个groupNode。下一层(groupNodes 的子节点)包含顶部节点的所有原始子节点,下一层包含每个父节点 2 个 groupNodes(如果组不为空),依此类推。这就是你想要的,对吧?
  • 是的,部分...这显示了如何从一般树创建我的树,但我想知道如何以有效的方式遍历我的结构
  • 啊,好吧,我以为你已经有了想要树使用的遍历函数。但是现在你必须告诉我更多——你所说的遍历到底是什么意思?通过 ID 获取节点,还是向下/向上/跨越一定距离?如果您正在寻找二叉树的效率,那么这意味着根据条件寻找节点 - 例如,不是“找到具有 nodeId A 的节点”,而是“在 true/true/false/true/false 找到节点”。
  • 好的,你为什么不直接告诉我你想要的最终结果是什么,我们就从那里开始工作?在我看来,您想要一棵具有字符串 id 的节点树,并且您希望能够以二叉树的效率通过 nodeId 进行搜索。那是对的吗?这就是你想要的一切吗?
猜你喜欢
  • 1970-01-01
  • 2021-07-02
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
相关资源
最近更新 更多