在解决排序算法方面,我需要一些建议。该特定算法将具有包含n个项目的列表的输入。每个项目都有一个id和一个父ID。像这样:
[
{id : 1, parent_id : 0},
{id : 2, parent_id : 1},
{id : 3, parent_id : 1},
{id : 4, parent_id : 2},
{id : 5, parent_id : 4},
{id : 6, parent_id : 0}
]
这是预期的结果:
[
{id : 1, parent_id : 0, children:
[
{id : 2, parent_id : 1, children:
[
{id : 4, parent_id : 2, children:
[
{id : 5, parent_id : 4}
]}
]
},
{id : 3, parent_id : 1}
]},
{id : 6, parent_id : 0}
]
我最初的想法是将算法分成层级,递归地解析每个级别。所以它在理论上看起来像这样:
我刚刚开始研究一些函数式编程范例,并开始阅读更多有关算法和分析的内容,因为我不熟悉递归思考。
所以我的问题是:
到目前为止,我已经创建了一个能够达到2级层次结构的算法。它看起来像这样(目前用php编写,只是概念代码的证明):
function sortParentsChildren($unsortedList, $parentIDKey = "parent_id", $childNameKey = "children"){
$sortedList = array();
foreach($unsortedList as $key => $value){
$children = array();
//See if there are any children for this item
foreach($unsortedList as $skey => $svalue){
if($value["id"] == $svalue[$parentIDKey]){
$children[] = $svalue;
}
}
//Add all items with parent id = 0 to the root
if($value["parent_id"] == 0){
$sortedList[$key] = $value;
}
//Check if there were any children
if(sizeof($children) > 0){
//Search each children and see if they have any matches
foreach($children as $ckey => $cvalue){
foreach($unsortedList as $s2key => $s2value){
if($cvalue["id"] == $s2value[$parentIDKey]){
$children[$ckey][$childNameKey][] = $s2value;
}
}
}
$sortedList[$key] = $value;
$sortedList[$key][$childNameKey] = $children;
}
}
return $sortedList;
}
答案 0 :(得分:1)
您通常使用某种字典数据结构来执行此操作。基本上,你有这样的结构:
Node
{
int id;
int parent;
Node[] children;
}
您将其保存在由id键入的字典或关联数组中。创建一个id值为0且父id为-1的节点。
按父ID对输入数组进行排序,然后浏览列表。对于每个项目,将其添加到字典中。还要查找其父节点(由于输入列表已按父ID排序,因此已在字典中),并将新节点添加到父节点的子节点中。
完成后,node [0]包含构造的层次结构。
我不是一个PHP程序员,所以你必须使用伪代码:
Nodes = new associative array
Nodes[0] = new Node(0, -1)
sortedInput = sort input by parent id
foreach item in sortedInput
Nodes[item.id] = new Node(item.id, item.parent);
//Nodes[item.parent].Children.Add(Node);
// Above line commented and replaced with this.
Nodes[item.parent].Children.Add(Nodes[item.id]);
end
// Nodes[0] contains the hierarchy
OutputNode(Nodes[0], "")
输出层次结构的函数是递归的:
OutputNode(Node, indent)
print indent, Node.id, Node.parent
foreach (child in Node.children)
OutputNode(child, indent+" ");
end
end
答案 1 :(得分:1)
不需要递归。只是对象的简单循环。对于每个对象,如果其parent_id为0,则将其复制到答案数组。否则,通过它在数组中的位置访问父对象,并将当前对象追加到其子列表中。
以下是您的阵列的工作原理。请仔细注意更新对象一旦更新该对象的所有副本这一事实的结果。
0: Start
answer = []
objects = [
{id : 1, parent_id : 0},
{id : 2, parent_id : 1},
{id : 3, parent_id : 1},
{id : 4, parent_id : 2},
{id : 5, parent_id : 4},
{id : 6, parent_id : 0}
]
1: Append object 1 to answer
answer = [
{id : 1, parent_id : 0}
]
objects = [
{id : 1, parent_id : 0},
{id : 2, parent_id : 1},
{id : 3, parent_id : 1},
{id : 4, parent_id : 2},
{id : 5, parent_id : 4},
{id : 6, parent_id : 0}
]
2: Append object 2 to children of object 1
answer = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1}
]}
]
objects = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1}
]},
{id : 2, parent_id : 1},
{id : 3, parent_id : 1},
{id : 4, parent_id : 2},
{id : 5, parent_id : 4},
{id : 6, parent_id : 0}
]
3: Append object 3 to children of object 1
answer = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1},
{id : 3, parent_id : 1}
]}
]
objects = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1},
{id : 3, parent_id : 1}
]},
{id : 2, parent_id : 1},
{id : 3, parent_id : 1},
{id : 4, parent_id : 2},
{id : 5, parent_id : 4},
{id : 6, parent_id : 0}
]
4: Append object 4 to children of object 2
answer = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3}
]}
]}
]
objects = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3}
]}
]},
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3}
]},
{id : 4, parent_id : 2},
{id : 5, parent_id : 4},
{id : 6, parent_id : 0}
]
5: Append object 5 to children of object 4
answer = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3, children : [
{id : 5, parent_id : 4}
]}
]}
]}
]
objects = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3, children : [
{id : 5, parent_id : 4}
]}
]}
]},
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3, children : [
{id : 5, parent_id : 4}
]}
]},
{id : 4, parent_id : 3, children : [
{id : 5, parent_id : 4}
]}
{id : 5, parent_id : 4},
{id : 6, parent_id : 0}
]
6: Append object 6 to answer
answer = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3, children : [
{id : 5, parent_id : 4}
]}
]}
]},
{id : 6, parent_id : 0}
]
objects = [
{id : 1, parent_id : 0, children : [
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3, children : [
{id : 5, parent_id : 4}
]}
]}
]},
{id : 2, parent_id : 1},
{id : 3, parent_id : 1, children : [
{id : 4, parent_id : 3, children : [
{id : 5, parent_id : 4}
]}
]},
{id : 4, parent_id : 3, children : [
{id : 5, parent_id : 4}
]}
{id : 5, parent_id : 4},
{id : 6, parent_id : 0}
]