Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 使用order属性对对象重新排序_Algorithm_Language Agnostic - Fatal编程技术网

Algorithm 使用order属性对对象重新排序

Algorithm 使用order属性对对象重新排序,algorithm,language-agnostic,Algorithm,Language Agnostic,考虑具有顺序属性的对象。对象将基于此属性进行排序 考虑到以下限制和操作,您将如何分配order属性 操作(按重要性排序) 推送(对象):在索引0处插入对象 交换(indexN,indexM):将索引N处的对象与索引M处的对象交换 删除(对象):删除对象。其余元素必须保持相同的顺序 插入(对象):按给定顺序插入对象 限制 更改对象的顺序属性非常昂贵。应尽量减少变化 顺序可以是整数或浮点,这是实现所需的 如果订单保持唯一,则操作插入必须包括一种方法,以修复已存在的订单,并进行尽可能少的更改。可以假设

考虑具有
顺序
属性的对象。对象将基于此属性进行排序

考虑到以下限制和操作,您将如何分配
order
属性

操作(按重要性排序)

推送(对象)
:在索引0处插入对象

交换(indexN,indexM)
:将索引N处的对象与索引M处的对象交换

删除(对象)
:删除对象。其余元素必须保持相同的顺序

插入(对象)
:按给定顺序插入对象

限制

更改对象的
顺序
属性非常昂贵。应尽量减少变化

顺序
可以是整数或浮点,这是实现所需的

如果
订单
保持唯一,则操作
插入
必须包括一种方法,以修复已存在的
订单
,并进行尽可能少的更改。可以假设,如果插入的对象与现有对象具有相同的
顺序
,则有另一个标准来确定哪一个先插入

如果
顺序
允许重复,则操作
交换
必须包括一种方法,以修复交换元素的
顺序
,如果它们具有相同的值,则再次进行尽可能少的更改。首选惩罚操作
插入


很可能这个问题已经有了一个名称和一个已知的解决方案,但我一眼就找不到它。

使用浮点表示顺序

对于
push
,为对象指定一个顺序,该顺序等于现在位于索引1的对象的顺序减去1(
list[0]。order=list[1]。order-1

对于
swap
,交换两个对象的顺序(
temp=list[i];list[i]=list[j];list[j]=list[i];temp=list[i]。order;list[i]。order=list[j]。order;list[j]。order=temp
);如果这可能会导致一致性问题,那么理想情况下,您可以在元素上放置一个
transit
标志,以指示它们的顺序正在被修改,或者在最坏的情况下锁定对象,直到它们一致为止

对于
remove
,什么也不做-列表中的对象仍然是有序的,您刚刚在序列中引入了一个间隙,这应该不是问题

insert
是唯一有问题的。如果在索引
i
处插入元素,则其顺序等于索引
i-1
i+1
处元素顺序的平均值(
list[i].order=(list[i-1].order+list[i+1].order)/2
)。验证此新顺序不等于索引
i-1
i+1
list[i].order!=list[i-1].order&&list[i].order!=list[i+1].order
)处的顺序-这将表明您已命中机器ε。当这种情况发生时(如果发生这种情况,应该很少发生),您有两种选择:

  • 咬紧牙关,对整个列表重新排序,即在索引0处分配一个
    0
    顺序,在索引1处分配一个
    1
    顺序。。。索引n处的订单
    n
  • 进行本地重新订购,以尽量降低成本。将相邻元素重新排序到列表[i-1]。顺序=(列表[i-2]。顺序+列表[i-1]。顺序)/2
  • 列表[i+1]。顺序=(列表[i+2]。顺序+列表[i+1]。顺序)/2
    ,然后重新排序
    列表[i]=(列表[i-1]+列表[i+1])/2
    ,再次验证您在[i-1]和[i+1]处没有到达机器上位机重新排序-如果您已到达机器ε,例如[i-1],则首先将[i-2]重新排序到
    列表[i-2]。顺序=(列表[i-3]。顺序+列表[i-2]。顺序)/2
    ,然后重新排序[i-1]。如果[i-2]重新排序命中机器ε,则首先重新排序[i-3],依此类推。(如果您到达列表的末尾,那么只需减少元素[0]的顺序或增加元素[n]的顺序。)正如您所看到的,在最坏的情况下,您得到的级联重新排序要比您简单地咬紧牙关并重新排序整个列表更昂贵;然而,重新排序很可能仍然是局部的。一个很好的折衷办法是,如果级联次数太多(合理的值为“太多”),则执行完整的重新排序
    简单地说,双链接列表为您提供:

    • push(object)
      :O(1),给它比当前头小1的命令
    • 交换(indexN,indexM)
      :O(n),交换订单
    • 删除(对象)
      :O(1),不要触摸任何订单
    • 插入(对象)
      :O(n),插入顺序,以便列表按顺序排序

    可能不太好,因为第二个最重要的一个有一个昂贵的(变更单)操作。

    您能提供一个示例用例吗?可能有助于更好地了解您来自何方。谢谢您的询问。这是一个数字对象列表,可以手动排序,可以在许多设备上同时编辑。因此,可以在具有相同顺序的不同设备中添加对象。同步必须处理这个问题。嗯,好的。您希望如何处理不兼容的订购,例如,一台设备有A、B、C、D,另一台设备有D、C、B、A,您在同步时做什么?这将超出问题的范围。我更喜欢把重点放在推、交换、删除和插入这四个原语上。我不明白。您可以通过交换将ABCD转换为DCBA。用户可以做什么,不可以做什么?+1感谢您提供的详细答案Zim Zam。我想你的意思是
    push
    而不是第一个
    insert
    。另外,
    insert
    不是索引而是顺序,因此您的解决方案需要搜索整个列表以找到适合它的索引,然后用相邻对象的中间部分替换其顺序,然后处理机器ε。这很好。最后,你会使用零还是零