将子代值求和并将结果保存到Java中的n元树中

时间:2018-09-27 08:50:44

标签: javascript arrays recursion tree

我在Javascript中有一棵具有以下结构的树,这是一个简单的示例:

tree: [
    {
      id: 'A'
      parents: []
      children: ['B']
      value: 1
    },
    {
      id: 'B'
      parents: ['A']
      children: ['C', 'D']
      value: 1
    },
    {
      id: 'C'
      parents: ['B']
      children: []
      value: 1
    },
    {
      id: 'D'
      parents: ['B']
      children: []
      value: 1
    }
]

      A
      |
      B
     / \
    C   D

每个节点可以有不固定数量的子节点,我正在使用parents数组来知道树的根(当parents数组为空时)。

我想做的是一个递归函数:子值的总和保存在父级中(覆盖值)。如果只有一个孩子,则该孩子的值将保存在父母中。因此,值会累积到根。

树结构还好吗?我该怎么做?

谢谢。

编辑:

预期结果:

tree: [
        {
          id: 'A'
          parents: []
          children: ['B']
          value: 2
        },
        {
          id: 'B'
          parents: ['A']
          children: ['C', 'D']
          value: 2
        },
        {
          id: 'C'
          parents: ['B']
          children: []
          value: 1
        },
        {
          id: 'D'
          parents: ['B']
          children: []
          value: 1
        }
    ]

另一个例子:

       A
     /   \
    B     E
   / \    |
  C   D   F

所有节点值= 1。

预期结果:

tree: [
        {
          id: 'A'
          parents: []
          children: ['B','E']
          value: 3
        },
        {
          id: 'B'
          parents: ['A']
          children: ['C', 'D']
          value: 2
        },
        {
          id: 'C'
          parents: ['B']
          children: []
          value: 1
        },
        {
          id: 'D'
          parents: ['B']
          children: []
          value: 1
        },
        {
          id: 'E'
          parents: ['A']
          children: ['F']
          value: 1
        },
        {
          id: 'F'
          parents: ['E']
          children: []
          value: 1
        }
    ]

A值= B值+ E值。

B值= C值+ D值。

E值= F值

3 个答案:

答案 0 :(得分:2)

请注意,树形结构与您的树形结构不同,但是您也可以根据需要插入其他属性(例如, id )。

const tree = {
    value: 1,
    children: [{
        value: 1,
        children: [{
            value: 1,
            children: null
        },
        {
            value: 1,
            children: null
        }]
    }]
};

function sum(node) {
    var childSum = 0;
    if (!node.children) return node.value;
    for (var i = 0; i < node.children.length; i++) {
        childSum += sum(node.children[i]);
    }
    node.value = childSum;
    return childSum;
}

sum(tree);

答案 1 :(得分:1)

您可以将根元素以及每个项目的引用存储在哈希表中,以加快访问速度。然后通过对孩子使用递归来迭代根元素以获取所需的总和。

这种方法只是更新给定的数组。

function update(array) {
    var root = [],
        references = array.reduce((r, o) => {
            if (!o.parents.length) {
                root.push(o.id);
            }
            r[o.id] = o;
            return r;
        }, Object.create(null));
    
    root.reduce(function sum(s, id) {
        var o = references[id];
        return s + (o.value = o.children.reduce(sum, 0) || o.value);
    }, 0);

    return array;
}


var data1 = [{ id: 'A', parents: [], children: ['B'], value: 1 }, { id: 'B', parents: ['A'], children: ['C', 'D'], value: 1 }, { id: 'C', parents: ['B'], children: [], value: 1 }, { id: 'D', parents: ['B'], children: [], value: 1 }],
    data2 = [{ id: 'A', parents: [], children: ['B', 'E'], value: 1 }, { id: 'B', parents: ['A'], children: ['C', 'D'], value: 1 }, { id: 'C', parents: ['B'], children: [], value: 1 }, { id: 'D', parents: ['B'], children: [], value: 1 }, { id: 'E', parents: ['A'], children: ['F'], value: 1 }, { id: 'F', parents: ['E'], children: [], value: 1 }]

console.log(update(data1));
console.log(update(data2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

let tree = [
  {
    id: 'A',
    parents: [],
    children: ['B'],
    value: 1
  },
  {
    id: 'B',
    parents: ['A'],
    children: ['C', 'D'],
    value: 1
  },
  {
    id: 'C',
    parents: ['B'],
    children: [],
    value: 1
  },
  {
    id: 'D',
    parents: ['B'],
    children: [],
    value: 1
  }
];
let leafNodes = [];
function ArrayToObject(array, keyField) {
  return array.reduce((obj, item) => {
    obj[item[keyField]] = item;
    if (!item.children.length && !leafNodes.includes(item[keyField])) leafNodes.push(item[keyField]);
    return obj;
  }, {});
}


let treeObject = ArrayToObject(tree, 'id');

addSumToParentNode(leafNodes);

function addSumToParentNode(childNodes) {
  if (childNodes.length) {
    let parentNodes = [];
    childNodes.map(child => {
      if (treeObject[child].parents.length) {
        let parent = treeObject[child].parents[0];
        if (!parentNodes.includes(parent)) parentNodes.push(parent);
        treeObject[parent].value += treeObject[child].value;
      }
    });
    addSumToParentNode(parentNodes);
  }
}

console.log(Object.values(treeObject));