Suppose I have a list/array like:
[
{ id: 1, parent: null },
{ id: 2, parent: 1 },
{ id: 4, parent: 2 },
{ id: 5, parent: 3 },
{ id: 6, parent: 2 },
{ id: 3, parent: 4 }
]
And I want to convert it to a tree like so:
{
id: null,
children: [
{
id: 1,
children: [
{
id: 2,
children: [
{
id: 4,
children: [
{
id: 3,
children: [
{
id: 5,
children: []
}
]
}
]
},
{
id: 6,
children: [
]
}
]
}
]
}
]
}
I can do this trivially with the following (pseudocode) function:
function GetChildren(rootNode, inputList) {
for (item in inputList) {
if (item.parent == rootNode.id) {
childNode = {
id: item.id,
children: []
}
GetChildren(childNode, inputList)
rootNode.children.append(childNode)
}
}
}
I believe this will run with time complexity of O(n²). Is there an algorithm that can do this faster? I have seen some similar sounding questions for BSTs, but this is not a BST.
Note the following:
- A node may have unlimited children
- The tree can be infinitely deep
- The items in the list may appear in any order (child may appear before parent)
I had a thought about trying to only pass the part of the list without the parent, so as you recur you iterate through a progressively smaller list. I don't know if that would actually save time though:
function GetChildren(rootNode, inputList) {
for (item in inputList) {
listWithoutParent = inputList.remove(rootNode) // O(?)
if (item.parent == rootNode.id) {
childNode = {
id: item.id,
children: []
}
GetChildren(childNode, listWithoutParent)
rootNode.children.append(childNode)
}
}
}