堆中有效的簿记

时间:2016-08-24 14:25:30

标签: python heap

我正在尝试使用列表数据结构实现堆。我还想跟踪列表中元素的位置,以便轻松删除。我的实现涉及循环遍历整个列表以在插入/删除组合之后更新位置。我担心这会将时间复杂度从O(log n)提高到O(n)。 有没有更好的方法来跟踪元素的位置?目前,更新方法是负责簿记的。

{
  "_meta": {
    "sources": [
      "loopback/common/models",
      "loopback/server/models",
      "../common/models",
      "./models"
    ],
    "mixins": [
      "loopback/common/mixins",
      "loopback/server/mixins",
      "../common/mixins",
      "./mixins"
    ]
  },
  ... ,
  "user": {
    "dataSource": "mysql",
    "public": true,
    "options": {
      "emailVerificationRequired": true
    }
  },
...
}

1 个答案:

答案 0 :(得分:1)

如果您正在构建二进制堆,我知道的加速任意删除或更改优先级的最佳方法是创建哈希映射。键是优先级队列中的项,值是数组中的当前位置。将项目插入队列时,可以使用项目的当前位置向哈希映射添加条目。

然后,每次项目在队列中移动时,都会在哈希映射中更新其值。因此,每次在插入或删除期间进行交换时,都会更新该哈希映射中的交换项的值。

要删除任意项目,请执行以下操作:

  1. 在哈希映射中查找项目的位置。
  2. 删除哈希映射中的项目条目。
  3. 将堆中的最后一项移动到已删除项的位置,并在哈希映射中更新其位置。
  4. 根据需要在堆中向上或向下筛选新项目,更新哈希映射中所有受影响节点的位置。
  5. 这种方法运行得相当不错,但如果你的堆很大,它在内存方面可能相当昂贵。

    其他堆数据结构,如Fibonacci堆,配对堆,Skew堆,甚至是作为二叉树实现的二进制堆,可以与单个堆节点一起工作,而不是在数组中使用隐式节点,因此可以直接访问而无需中间哈希表的。它们确实需要比作为数组实现的二进制堆更多的内存,但可能效率更高。

    顺便说一下,如果你决定尝试其中一种替代结构,我建议你看一下配对堆。它的渐近性能几乎与Fibonacci堆一样好,并且很多更容易实现。我的实际表现还没有很好的数据。