我目前正在处理一个最小优先级队列,该队列在添加项目时会自行排序。建议的实现将新项添加到已排序的ArrayList的末尾,然后通过列表返回以查找项正确的位置。因此,它与列表中的每个前一个元素交换,直到添加的项目按顺序排列。
我建议在此方法之前使用的实现包括通过排序列表进行比较,标记要插入项的索引,然后使用Java的add(int index,Object O)方法而不是仅添加到最后。
我试图理解2之间的性能差异。我理解如果我插入,则必须纠正所有尾随索引(由类方法处理)。但这是否比在列表中交换效率低得多?
提前感谢任何解释
答案 0 :(得分:1)
如前所述,这两个选择都将在O(n)时间内运行(我认为)。然而,第二个选项(即你的初始实现)可能会有更好的常数因素,因为同时移动一组元素可以(并且可能会)比一次移动元素更有效,特别是如果你必须移动大量的元素。所以我会说你的初始实现效率更高,除非你的最终插入点几乎总是接近数组的末尾,此时System.arraycopy()
的开销可能占据实际工作所需的时间 - 但不是很多。
我认为您可以将这两种情况视为近似比较bubblesort(建议实现)和插入排序(初始实现)的单次迭代。两者都具有相同的时间复杂度,但是由于操作较少,单次迭代的插入排序几乎总是(或者可能总是?)运行得更快。
以此为例(假设可调整大小的数组):
int[] a = new int[] {1, 2, 4, 5};
并说你要插入3
。
您的初始实施将是这样的:
index == 2
。System.arraycopy()
的实现方式)。结果为{1, 2, 0, 4, 5}
{1, 2, 3, 4, 5}
。总计:3次比较,3次操作。
您的新实施将是这样的:
{1, 2, 4, 5, 3}
。{1, 2, 4, 3, 5}
{1, 2, 3, 4, 5}
。总计:3次比较,7次操作。
作为旁注,您可能最好使用二分搜索来查找插入点而不是直线搜索。