简短答案:您不能。
答案略长:
您将需要额外的空间来存储条目的“年龄”,这将使您能够区分相同的优先级。而且,您需要空间来获取允许快速插入和检索的信息。加上您的有效负载(值和优先级)。Ω(n)Ω(n)
而且,对于您存储的每个有效负载,您都可以“隐藏”地址中的某些信息(例如,表示Y早于X)。但是在该“隐藏”信息中,您将隐藏“年龄”或“快速检索”信息。不是都。addr(X)<addr(Y)
不精确的片状伪数学的答案很长:
注意:如上所述,第二部分的末尾是粗略的。如果有一些数学专家可以提供更好的版本,我将不胜感激。
让我们考虑一下X位机器(例如32或64位)上涉及的数据量,其中记录(值和优先级)为机器字。P
您有一组可能的记录,这些记录的一部分是有序的:和但无法比较和。(a,1)<(a,2)(a,1)=(a,1)(a,1)(b,1)
但是,您希望能够根据插入记录的时间来比较记录集中的两个不可比较的值。因此,这里有另一组值:已插入的值,并且您要用部分顺序对其进行增强:如果在之前插入。X<YXY
在最坏的情况下,你的记忆将充满形式的记录(用对于每一个不同的),所以你必须以决定哪一个去当插入时间完全依赖首先出来。(?,1)?
- 插入时间(相对于仍在结构中的其他记录)需要位信息(具有P字节有效负载和可访问内存字节)。X−log2(P)2X
- 有效负载(记录的值和优先级)需要机器字信息。P
这意味着您必须为存储的每个记录以某种方式存储额外的信息位。这就是为记录。X−log2(P)O(n)n
现在,每个内存“单元”为我们提供多少信息?
现在,我们假设(有效载荷至少为一个机器字宽(通常为一个八位位组))。这意味着,因此我们可以将插入顺序信息放入单元格的地址中。这就是堆栈中发生的事情:地址最低的单元格首先进入堆栈(最后退出)。P≥1X−log2(P)<X
因此,要存储所有信息,我们有两种可能性:
- 将插入顺序存储在地址中,并将有效负载存储在内存中。
- 将两者都存储在内存中,并保留地址以用于其他用途。
显然,为了避免浪费,我们将使用第一种解决方案。
现在开始操作。我想您希望拥有:
- Insert(task,priority),时间复杂度为。O(logn)
- StableExtractMin()具有时间复杂度的。O(logn)
让我们看一下:StableExtractMin()
真正通用的算法是这样的:
- 在找到具有最低优先级和最短“插入时间”的。O(logn)
- 从的结构中删除它。O(logn)
- 把它返还。
例如,在堆的情况下,其组织会稍有不同,但工作是相同的:1.在找到min记录
2.在从结构中删除它
。3.修复一切,以便下次#1和#2仍为即“修复堆”。这需要在“ O(log n)”中完成。4.返回元素。0(1)O(1)O(1)
回到一般算法,我们看到要找到时间的记录,我们需要一种快速的方法来在候选对象中选择正确的一个(最坏的情况是,内存是充分)。O(logn)2(X−log2(P))
这意味着我们需要存储位信息才能检索该元素(每个位将候选空间一分为二,因此我们有分,这意味着时间复杂度)。X−log2(P)O(logn)O(logn)
这些信息位可能存储为元素的地址(在堆中,最小值位于固定地址),或者例如,使用指针(在二进制搜索树中(带有指针),您需要遵循以获得平均值)。O(logn)
现在,当删除该元素时,我们需要增加下一个min记录,以便它具有正确的信息量以允许下次进行检索,也就是说,它具有位区别于其他候选人的信息。O(logn)X−log2(P)
也就是说,如果尚没有足够的信息,则需要添加一些信息。在(非平衡)二进制搜索树中,信息已经存在:您必须将NULL指针放在某个位置以删除元素,并且无需任何进一步操作,就可以在时间搜索BST 。平均。O(logn)
在此之后,它还是有点粗略的,我不确定如何制定。但是我有一种强烈的感觉,即您集合中的每个其余元素都需要具有位信息,这些信息将有助于查找下一个分钟并用足够的信息对其进行扩充,以便可以在下一次时间。O (l o g n )X−log2(P)O(logn)
插入算法通常只需要更新此信息的一部分,我认为快速执行它不会花费更多(从内存角度而言)。
现在,这意味着我们需要为每个元素存储更多的信息位。因此,对于每个元素,我们都有:X−log2(P)
- 插入时间位。X−log2(P)
- 有效载荷机器字。P
- “快速搜索”信息,位。X−log2(P)
由于我们已经使用内存内容来存储有效负载,并使用地址来存储插入时间,因此我们没有剩余空间来存储“快速搜索”信息。因此,我们必须为每个元素分配一些额外的空间,以便“浪费”额外空间。Ω(n)