最近在比较Dijkstra+各种优先队列组合的效率。
这个想法源于算法课的作业。作业要我们用现成的库(LEDA)来比较。我比较出来的结果和预期相差甚远,怀疑是不是库的问题。
于是,这次我亲手写了所有的代码,再比较一次。
Binomial Heap虽然经常被各种教科书提到,不过实际应用不是很多。
理由很简单:他没有堆简单,也没有斐波那契堆高效。
然而,优美的结构(虽然不是很容易实现,可能是我写的不好)让它在各个教材中都占有一席之地。
Binomial Heap所有操作复杂度都是O(logn)的。
一个Binomial Heap是一个“二项树”的链表,几乎所有操作都基于merge方法。
每个节点都用“做孩子又兄弟”表示(这样表示似乎可以减少指针的浪费:正常表示方法中大量叶节点都是null,而左孩子右兄弟表示中null出现次数减少了一半,因为叶节点只有一个指针指向null)
以前用vector写过一个Binomial Heap,感觉有些山寨。这次正儿八经的用linked list写了一遍。
merge方法说起来简单,其实却相当难写……不知道有啥简洁的实现方法不。
delete min方法讲起来也很简单,不过merge之前要把chid的链表反向一下,因为child链表中元素的degree是递减的。
目前实验结果表明dijkstra+Binomial Heap的表现几乎和普通堆持平,有时候甚至超过普通堆。