Php 对松散连接的数据进行排序,使人联想到单链表 我正在寻找一个有效的解决方案来排序链接数据。

Php 对松散连接的数据进行排序,使人联想到单链表 我正在寻找一个有效的解决方案来排序链接数据。,php,arrays,sorting,computer-science,singly-linked-list,Php,Arrays,Sorting,Computer Science,Singly Linked List,这是上下文: 程序返回一个对象数组,每个对象包含两个变量:id和previous_id。id是唯一标识符,previous_id指数组中对象的另一个id。数组中对象的顺序是随机的 显然,排序是这样的:在排序数组中,第一个对象是前一个_id为null的对象。数组中的下一个对象应始终是其上一个_id与当前对象的id对应的对象,或者它是最后一个对象 按照上述顺序对这些变量进行排序的有效算法是什么? 我的直觉表明,有一种简单的方法可以对这些变量进行排序。这些对象的表示方式让我想起了一个单链表。但我似乎找

这是上下文:

程序返回一个对象数组,每个对象包含两个变量:id和previous_id。id是唯一标识符,previous_id指数组中对象的另一个id。数组中对象的顺序是随机的

显然,排序是这样的:在排序数组中,第一个对象是前一个_id为null的对象。数组中的下一个对象应始终是其上一个_id与当前对象的id对应的对象,或者它是最后一个对象

按照上述顺序对这些变量进行排序的有效算法是什么?

我的直觉表明,有一种简单的方法可以对这些变量进行排序。这些对象的表示方式让我想起了一个单链表。但我似乎找不到一个优雅的解决方案

我当前的算法过于复杂,工作原理如下:

  • 首先,我们通过构建一个 数组。hashmap是通过迭代数组和映射来构建的 当前对象id的键和当前对象的值 对象,包装在大小为1的数组中
这些数组的目标是始终具有正确的顺序,
除了第一个元素之外,它可以有一个可能指向 指向不在其自身数组中的元素,或为null

哈希映射中指向此数组的键始终是数组中最后一个元素的id

  • 然后我们继续在hashmap上循环,直到hashmap的长度 小于或等于1

  • 在循环中,我们在hashmap上迭代

  • 如果当前散列项的键不为null,则取第一个 数组的元素,我们称之为head。我们还取数组的最后一个元素,我们称之为butt

  • 现在,我们可以将两个数组合并为一个数组,方法是在哈希映射中找到一个数组,该数组的键等于迭代中当前数组的头的上一个_id,并删除哈希映射中找到的数组

伪代码如下所示:

$tbr=$this->prepareDataForSorting();
而(计数($tbr)>1){
foreach($key=>$children){
$head=array_first($children);
如果($head->previousId!==null){
$butt=数组的最后一个($children);
$tbr[$butt->id]=数组合并($tbr[$head->previousId],$children);
未设置($tbr[$head->previousId]);
}
}
}
返回$tbr[数组\键\首($tbr)];
其中,分拣准备程序的实施方式如下:

$tbr=[];
foreach($this->childrenas$child){
$tbr[$child->id]=[$child];
}
返回$tbr;
这个算法的问题是它根本不是轻量级的。它需要哈希映射作为辅助数据结构以及O(n^2)算法。我觉得应该有一个更简单的方法

答案已张贴在下面。我决定为未来的访问者提供它的php实现:

$mapping=$this->mapData();
$current=$mapping[null]??无效的
$tbr=[];
while($current!==null){
$tbr[]=$current;
$current=$mapping[$current->id]??空;
}
返回$tbr;
使用地图数据:

$tbr=[];
foreach($this->childrenas$child){
$tbr[$child->previousId]=[$child];
}
返回$tbr;
  • 单纯的美丽

    • 你可以用更好更简单的方式实现你想要的。 我的建议如下:

      • 创建哈希映射
      • 在数组上迭代,对于数组中的每个条目,在哈希映射中创建一个条目,其键和值分别为
        previous_id
        和迭代中的当前条目
      • 最后,您需要获取key
        null
        的散列值(因为您的第一个项的
        上一个\u id
        为null),将其值推送到最终数组,并使用当前项的
        id
        作为hashmap的新键
      • 执行最后一步,直到最终数组的长度与原始数组的长度相同

      这种方法的复杂性是O(n),与O(n^2)相比非常有效。

      不应该更简单的方法是将键作为prev_id和val作为id(通过
      O(n)
      )的映射,然后另一个
      O(n)
      循环以在新数组中对元素进行排序(现在您可以使用
      O(1)访问下一个元素)
      ?这让我想起了我对这个问题的评论……如果你接受了它并给出了完整的答案,至少添加伪代码和示例,这会更加优雅。我知道我想得太多了