Algorithm Java中实现队列的最快方法

Algorithm Java中实现队列的最快方法,algorithm,data-structures,queue,Algorithm,Data Structures,Queue,任务是使用以下方法在java中实现队列: 排队//向队列添加元素 退出队列//从队列中删除元素 peek中位数//查找中位数 peek最小值//查找最小值 peakMaximum//find maximum 大小//获取大小 假设所有方法都以相同的频率被调用,任务是以最快的速度实现 我目前的做法是: 除了队列之外,还要维护一个排序的数组,这样排队和退队都是take-Ologn和Peek-Middian、Peek-Maximum、Peek-Minimum都是take-O1时间 请建议一种更快的方法

任务是使用以下方法在java中实现队列:

排队//向队列添加元素 退出队列//从队列中删除元素 peek中位数//查找中位数 peek最小值//查找最小值 peakMaximum//find maximum 大小//获取大小 假设所有方法都以相同的频率被调用,任务是以最快的速度实现

我目前的做法是: 除了队列之外,还要维护一个排序的数组,这样排队和退队都是take-Ologn和Peek-Middian、Peek-Maximum、Peek-Minimum都是take-O1时间


请建议一种更快的方法,假设所有方法的调用频率都相同。

好吧,你很接近了-但仍然缺少一些东西,因为从排序数组中插入/删除是启用的,因为插入的元素以1/2的概率位于数组的前半部分,您必须将以下所有元素向右移动,其中至少有n/2个元素,所以此操作的总体复杂性是平均+最坏情况

但是,如果您将已排序的DS切换为a/-您将通过缓存获得Ologn插入/删除和O1最小/最大/中值/大小

编辑:

除非将PEEKMEDIANT减少到OmegalogN,否则插入时无法获得比OlogN更好的结果,因为这样可以使排序比ONlogN更好:

首先,请注意,对于此处插入的每个高元素,中间值向右移动一个元素,高表示>=当前最大值。 因此,通过迭代执行:

while peekMedian() != MAX:
   peekMedian()
   insert(MAX)
   insert(MAX)
您可以找到排序数组的上半部分。 使用与insertMIN相同的方法,可以获得数组的最低一半

假设你有一个很小的o符号,比插入符号和O1中值更好,你得到了一个比ONlogN更好的排序,但是排序是OmegaNlogN的问题。
=>好吧,你很接近了-但是仍然缺少一些东西,因为从排序数组中插入/删除是打开的,因为插入的元素以1/2的概率位于数组的前半部分,并且你必须将以下所有元素向右移动,并且至少有n/2个元素,所以这个操作的总复杂度是平均+最坏情况

但是,如果您将已排序的DS切换为a/-您将通过缓存获得Ologn插入/删除和O1最小/最大/中值/大小

编辑:

除非将PEEKMEDIANT减少到OmegalogN,否则插入时无法获得比OlogN更好的结果,因为这样可以使排序比ONlogN更好:

首先,请注意,对于此处插入的每个高元素,中间值向右移动一个元素,高表示>=当前最大值。 因此,通过迭代执行:

while peekMedian() != MAX:
   peekMedian()
   insert(MAX)
   insert(MAX)
您可以找到排序数组的上半部分。 使用与insertMIN相同的方法,可以获得数组的最低一半

假设你有一个很小的o符号,比插入符号和O1中值更好,你得到了一个比ONlogN更好的排序,但是排序是OmegaNlogN的问题。
=>有一个更简单、也许更好的解决方案。如前所述,排序数组使排队和出列都打开,这不是很好

除了队列之外,还要维护两个已排序集。Java库提供了SortedSet等平衡搜索树。low集合按排序顺序存储第一个天花板n/2个元素。第二个高组有最后一个地板/2

注意:如果允许重复,您将不得不使用类似的东西,而不是常规的Java排序集

要排队,只需添加到队列和正确的集合。如有必要,通过移动一个元素在集合之间重新建立平衡:低集合中的最大元素移动到上集合,或高集合中的最小元素移动到低集合。退出队列需要相同的重新平衡操作

如果n为奇数,则查找中值只是查找低集中的max元素。如果n为偶数,则在低集合中找到max元素,在高集合中找到min元素,并将其平均

对于本机Java排序集实现平衡树,这将是所有操作的Olog n。编写代码将非常容易。大约60行

如果您为低集和高集实现自己的筛选堆,那么查找中间值操作将有O1,而所有其他操作将保持Olog n


如果您继续为低集和高集实现自己的,那么您也将拥有O1 insert。

有一个更简单、也许更好的解决方案。如前所述,排序数组使排队和出列都打开,这不是很好

除了队列之外,还要维护两个已排序集。Java库提供了SortedSet等平衡搜索树。low集合按排序顺序存储第一个天花板n/2个元素。第二个高组有最后一个地板/2

注意:如果允许重复,您将不得不使用类似的东西,而不是常规的Java排序集

要排队,只需添加 到队列和正确的集合。如有必要,通过移动一个元素在集合之间重新建立平衡:低集合中的最大元素移动到上集合,或高集合中的最小元素移动到低集合。退出队列需要相同的重新平衡操作

如果n为奇数,则查找中值只是查找低集中的max元素。如果n为偶数,则在低集合中找到max元素,在高集合中找到min元素,并将其平均

对于本机Java排序集实现平衡树,这将是所有操作的Olog n。编写代码将非常容易。大约60行

如果您为低集和高集实现自己的筛选堆,那么查找中间值操作将有O1,而所有其他操作将保持Olog n


如果继续并实现自己的低集和高集,那么也将有O1 insert。

维护排序数组在每次插入/删除最差情况下打开维护排序数组在每次插入/删除最差情况下打开case@amit-在维护额外的BST时,我们如何在恒定时间内获得中值?@user1628340缓存。在插入/删除时维护它非常简单,而且它仍然在插入的OlogN范围内/deletion@amit-我并不真正了解缓存。请详细说明。@user1628340每当您插入/删除一个元素时—找到新的中间值—并将其存储在一个名为“中间值”的变量中,当您请求中间值时—您只需要检索它。您可以进行一些优化,但没有任何优化可以提高渐进时间复杂度,因此我暂时忽略它们。@amit-您如何从Ologn中的bst中找到中值?@amit-在维护额外的bst时,我们如何在恒定时间中获得中值?@user1628340缓存。在插入/删除时维护它非常简单,而且它仍然在插入的OlogN范围内/deletion@amit-我并不真正了解缓存。请详细说明。@user1628340每当您插入/删除一个元素时—找到新的中间值—并将其存储在一个名为“中间值”的变量中,当您请求中间值时—您只需要检索它。您可以进行一些优化,但没有任何优化可以提高渐近时间复杂性,因此我暂时忽略它们。@amit-您如何从Ologn中的bst中找到中值?@gene-Set不允许重复值,而队列允许重复值!你能想出任何允许重复值的有效数据结构吗。我在上面加了一句注为NB的话。您需要多集来处理重复项。幸好谷歌在他们的收藏库中提供了这些…@gene-Set不允许重复值,而队列允许重复值!你能想出任何允许重复值的有效数据结构吗。我在上面加了一句注为NB的话。您需要多集来处理重复项。幸运的是谷歌在他们的收藏库中提供了这些。。。