我正在研究优先级队列和d-heap来实现这个数据结构。 我找到了这个数据类型定义:
类DHeap实现PriorityQueue :
的 数据 :
包含n个节点的d-heap T;每个节点包含一个元素(elem)和一个取自有序宇宙的键(key) 的 操作 :
findMin() - > elem T(n)= O(1)
insert(elem e,key k) T(n)= O(log n)
使用元素e和键k创建一个新节点v,使其成为T的叶子并恢复排序规则 删除(elem e) T(n)= O(d * log n)
在T的最后一级交换包含该元素的节点v和任何叶子u,然后删除v并恢复将节点u推到正确位置的排序规则。
decreaseKey(元素,键d) T(n)= O(log n)
increaseKey(元素,键d) T(n)= O(d * log n)
我省略了操作的完整细节,因为我的问题集中在删除如何在d * log n中执行删除并在log n中插入。
我知道d-1是在路径根叶节点的子节点之间寻找更小或更大节点密钥的时间,而log n是树的高度,所以d * log n是成本最坏情况下的比较 但是,我怎样才能找到包含d * log n中元素的节点? 我认为这个操作需要O(n)(访问堆的时间),操作成本忽略了这个细节。我错了吗?
另一个问题是:如何在基于链接的树中插入节点作为叶子?我需要一些指向缺少叶子的指针吗?但是我如何处理释放位置的删除?
希望收到回复,谢谢。
答案 0 :(得分:1)
但是,如何在d * log n中找到包含元素的节点?我认为这个操作需要O(n)(访问堆的时间),操作成本忽略了这个细节。我错了吗?
为了实现高效,您需要一个辅助数据结构,用于存储从元素到节点的映射。
另一个问题是:如何在基于链接的树中插入节点作为叶子?我需要一些指向缺少叶子的指针吗?但是我如何处理释放位置的删除?
简单的答案是使用数组,就像在二进制堆中一样。或者,你可以扩充堆节点以指向它们最左边的null子节点,这样找到下一个叶子就是O(log_d n)-time。保持指向下一个叶子的指针,保持完整根据需要进行d-ary树结构。