创建对具有无限子层次结构的页面进行排序的算法时的建议

发布于 2024-11-05 02:05:52 字数 2412 浏览 0 评论 0原文

在解决排序算法时我需要一些建议。这个特定的算法将有一个包含 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;
}

I need some advice when it comes to solving a sorting algorithm. This particular algorithm will have an input of a list with n items. Each item has an id and a parent id. Like this:

[
    {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}
]

Here's the expected result:

[
    {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}
]

My initial idea was split the algorithm into levels of hierarchy parsing each level recursively. So that it looks something like this in theory:

  • Compare each item in the unsorted list with all items to see if there are any matches, put each matches in a child node in each parent, put each parent in a sorted list variable.
  • Compare each item in the children node with all the items in the unsorted list to see if they have matches, put the matches in each child node into their own child node.
  • Continue last step until each level doesn't have anymore matches.

I have just started looking on some functional programming paradigms and started reading more about algorithm and analysis, just because I'm not familiar with thinking recursively.

So my questions are:

  • What are your advice when dealing with kind of logic?
  • How do I learn to think in the right way?
  • By looking at my current algorithm, I feel like I have grasped the concept except I don't really know how to make the second check work as a recursive solution. Am I far from going the right direction?

So far I have created an algorithm which will be capable of 2 levels of hierarchy. It looks something like this (currently written in php and is just proof of concept code):

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故笙诉离歌 2024-11-12 02:05:52

您通常会使用某种字典数据结构来完成此操作。基本上,您有这样的结构:

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

You'd typically do this with some kind of dictionary data structure. Basically, you have a structure like this:

Node
{
    int id;
    int parent;
    Node[] children;
}

You keep this in a dictionary or associative array keyed by id. Create a node with an id value of 0 and a parent id of -1.

Sort your input array by parent id and then go through the list. For every item, add it to the dictionary. Also look up its parent node (which is already in the dictionary because the input list has been sorted by parent id), and add the new node to the parent's children list.

When you've finished, node[0] contains the constructed hierarchy.

I'm not much of a PHP programmer, so you'll have to do with pseudocode:

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], "")

The function to output the hierarchy is recursive:

OutputNode(Node, indent)
    print indent, Node.id, Node.parent
    foreach (child in Node.children)
        OutputNode(child, indent+"  ");
    end
end
奢欲 2024-11-12 02:05:52

不需要递归。只是对对象进行简单的循环。对于每个对象,如果其parent_id为0,则将其复制到answer数组。否则,通过父对象在数组中的位置来访问父对象,并将当前对象附加到其子对象列表中。

以下是您的阵列的工作原理。请仔细注意更新对象一次会更新该对象的所有副本这一事实的结果。

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}
    ]

There is no need for recursion. Just a simple loop over the objects. For each object, if its parent_id is 0, copy it to the answer array. Else access the parent object by its location in the array, and append the current object to its list of children.

Here is how that works out for your array. Note carefully the result of the fact that updating an object once updates all copies of that object.

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}
    ]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文