【问题标题】:How to change preservation of recursion in a binary tree indexing?如何更改二叉树索引中递归的保留?
【发布时间】:2020-01-13 06:14:34
【问题描述】:

我用 JavaScript 编写了允许生成任何二叉树的代码(每个父节点都有 2 个子节点)。

用户可以通过名为“levels”的变量来指定他想要的树的层数。

代码:

function TreeNode(name, type, properties, children) {
    this.name = name;
    this.type = type;
    this.properties = properties;
    this.children = children;
}

var levels = 3;


prop = properties("Object_1");

var tree = new TreeNode("Object_1", "level_1", prop, []);

levels--;

var tempIndex = 2;

function generateArbitraryLevels(parent, levelsRemaining) {
    // last level
    if (levelsRemaining === 0) return;

    var currentLevel = parseInt(parent.type.split('_')[1]) + 1;
    var prop1 = properties("Object_" + tempIndex);

    parent.children.push(
        new TreeNode("Object_" + tempIndex++, "level_" + currentLevel, prop1, [])
    );


    generateArbitraryLevels(parent.children[0], levelsRemaining - 1);

    var prop2 = properties("Object_" + tempIndex);

    parent.children.push(
        new TreeNode("Object_" + tempIndex++, "level_" + currentLevel, prop2, [])
    );
    generateArbitraryLevels(parent.children[1], levelsRemaining - 1);

}

generateArbitraryLevels(tree, levels);
tree = JSON.stringify([tree]);

例如对于“levels” = 3,树看起来像:

树中的每个对象都有:

-name - 架构中的第一个字段,它应该包含对象的 ID,

-type - 第二个字段,它有关于对象级别的信息,

-属性 - 没关系,

-儿童

它工作正常,但我真的想更改对象索引。 树应如下所示:

所以索引应该从左到右。 我怎样才能做到这一点?也许循环会更好地达到这个目的?

【问题讨论】:

    标签: javascript json recursion binary-tree


    【解决方案1】:

    我相信您正在寻找 Breadth First 而不是您已实现的 Depth First。检查下面的链接以获取有关树中广度优先算法的更多信息https://www.cs.bu.edu/teaching/c/tree/breadth-first/

    您可以参考下面的代码以获取用例的示例实现

        const TreeNode = (name, type, properties, children) => ({
          name,
          type,
          properties,
          children,
        });
        
        const getNode = (index, level, properties) => {
          const name = `Object_${index}`;
          const type = `level_${level}`;
          return TreeNode(name, type, properties[name], []);
        };
        
        const generateTreeChildren = (node, currentLevel, maxLevels, index, properties) => {
          if (currentLevel > maxLevels) {
            return null;
          }
        
          const child1 = getNode(index, currentLevel, properties);
          const child2 = getNode(index + 1, currentLevel, properties);
        
          node.children = [child1, child2];
        
          generateTreeChildren(child1, currentLevel + 1, maxLevels, index + 2, properties);
          generateTreeChildren(child2, currentLevel + 1, maxLevels, index + 4, properties);
        };
        
        const generateTree = (maxLevels, properties) => {
          if (maxLevels === 0) {
            return null;
          }
        
          const node = getNode(1, 1, properties);
        
          generateTreeChildren(node, 2, maxLevels, 2, properties);
        
          return node;
        };
    
        console.info(JSON.stringify(generateTree(3, {})));

    【讨论】:

    • 不幸的是,每个级别都应该有 2^level 对象,并且每个级别中的索引应该来自范围:向左的分支应该只包括 2 的幂 (2^n),向右的分支应该包括只有 2^(n+1) - 1
    • 是的,这就是广度优先方法的用途。上面的代码你试过了吗?
    • 好的,我在您的代码中更改了两行: generateTreeChildren(child1, currentLevel + 1, maxLevels, 2*index, properties); generateTreeChildren(child2, currentLevel + 1, maxLevels, 2*index + 2, properties); 现在它可以按我的意愿工作了。谢谢。
    • 好的,在上面的代码中,属性应该是一个对象,因此您可能需要修改该部分,并且无论在何处使用属性,您都需要调用您的函数
    【解决方案2】:

    如果在添加下面的级别之前添加直接子级,那么它将以广度优先而不是深度优先的方式完成。我已经用下面的undefined 替换了对properties 的调用,因为它不包含在您问题的代码sn-p 中。

    function TreeNode(name, type, properties, children) {
        this.name = name;
        this.type = type;
        this.properties = properties;
        this.children = children;
    }
    
    var levels = 3;
    
    
    prop = undefined; // properties("Object_1");
    
    var tree = new TreeNode("Object_1", "level_1", prop, []);
    
    levels--;
    
    var tempIndex = 2;
    
    function generateArbitraryLevels(parent, levelsRemaining) {
        // last level
        if (levelsRemaining === 0) return;
    
        var currentLevel = parseInt(parent.type.split('_')[1]) + 1;
        var prop1 = undefined; // properties("Object_" + tempIndex);
    
        parent.children.push(
            new TreeNode("Object_" + tempIndex++, "level_" + currentLevel, prop1, [])
        );
    
        var prop2 = undefined; // properties("Object_" + tempIndex);
    
        parent.children.push(
            new TreeNode("Object_" + tempIndex++, "level_" + currentLevel, prop2, [])
        );
        
        generateArbitraryLevels(parent.children[0], levelsRemaining - 1);
        generateArbitraryLevels(parent.children[1], levelsRemaining - 1);
    }
    
    generateArbitraryLevels(tree, levels);
    tree = JSON.stringify([tree]);
    
    // Check tree is as expected
    console.log(tree);

    【讨论】:

    • 不幸的是,该解决方案还不够好那仍然是相同的索引-首先是分支索引。它进入最深层次,下一个分支等......我真的很想从左到右进行索引(级别索引)。向左的分支应仅包含 2 的幂 (2^n),向右的分支应仅包含 2^(n+1) - 1
    • 对象索引似乎与第二张图匹配,即。 Object_1是level_1,Object_2-Object_3是level_2,Object_4-Object_7是level_3?
    • 是的,但如果级别 > 3,则树不是应有的样子。索引应该是广度优先而不是深度优先
    猜你喜欢
    • 2014-01-02
    • 2021-07-03
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    相关资源
    最近更新 更多