我记得堆可用于搜索元素是否在其中,时间复杂度为 O(logN)。但突然我无法得到细节。我只能找到getmin delete add等。
有人可以给个提示吗?
我记得堆可用于搜索元素是否在其中,时间复杂度为 O(logN)。但突然我无法得到细节。我只能找到getmin delete add等。
有人可以给个提示吗?
您需要搜索堆中的每个元素以确定元素是否在其中。
不过,一种优化是可能的(我们在这里假设一个最大堆)。如果您到达的节点的值低于您正在搜索的元素,则无需从该节点进一步搜索。但是,即使进行了这种优化,搜索仍然是 O(N)(需要平均检查 N/2 个节点)。
为时已晚,但仍然为可能会在这里绊倒的人添加此内容。
实际上,在堆中搜索将需要 O(N) 时间。但是,如果您可以在一次预处理中按顺序弹出数组中的所有元素,您将得到一个 O(N.logN) 的排序数组。实际上是堆排序。现在可以在 O(logN) 时间内搜索到您的新排序数组。
为堆的值添加索引可以解决这个问题。在 python 中,它可以在字典的帮助下完成。每次在最小堆中执行操作时,更新字典中节点的索引。
如果您的最小堆的长度很大并且您想多次在最小堆中搜索,您应该只执行此操作。它需要一些额外的代码来跟踪索引,但这将使程序的速度至少提高 50 - 60%。
正如其他人所提到的,在 PriorityQueue 中的搜索是线性的,因为除了堆的根之外,它不知道在哪里寻找特定的键。这是与 BST 的主要区别,在 BST 中,您始终知道根据您正在搜索的值向左或向右。在堆中,最小的总是在根,孩子可以在左子树或右子树上。
但是,您可以修改 PriorityQueue 以保留一个附加索引数组,该数组将索引 k 映射到其在堆数组中的位置。这将允许以下操作:
void insert(int k, Item item)
: 插入item并将其与k关联,以便以后可以通过k直接访问它
Item get(k)
:返回与索引 k 关联的项目。这可能在堆中的任何地方。
void change(int k, Item item)
:将与k关联的项目更改为项目。这将需要“reheapify”以确保维持堆顺序。
实现有点棘手,因为您需要确保堆和索引数组始终同步并指向正确的对象。如果您已经知道如何实现常规堆,请尝试添加索引数组并查看需要更改哪些内容以保持正确的顺序。这是一个完整的实现https://algs4.cs.princeton.edu/24pq/IndexMinPQ.java.html
我认为您正在寻找的是 BST(二叉搜索树)。
在最坏的情况下,在堆中查找元素的时间复杂度仍然是 O(n)。如果你必须找到一个特定的元素,你应该使用二叉搜索树来计算 O(logn) 时间复杂度
堆更擅长查找/查找最大值 (O(1)),而 BST 擅长所有查找 (O(logN))。
在堆中,最高(或最低)优先级元素始终存储在根。但是,堆不是排序结构。可以认为是部分有序的。
我对它有点困惑,只是为了说清楚,对于堆(尚未排序),如果你想搜索一个项目,那么它O(n)
就像一个未排序的数组一样,但如果它是堆排序的,那么它意味着数组已经排序,所以在这种情况下,将需要O(log n)
(二分搜索)来搜索一个项目。