C++ 两堆合并算法
据我所知,存在一个二项式堆或所谓的可合并堆,用于合并两个堆。我的问题是,如果我将这两个堆复制到一个大数组中,然后执行堆构建过程,而不是动态地将它们合并到一个堆中,那么这是一个好方法还是一个坏方法C++ 两堆合并算法,c++,data-structures,binomial-heap,C++,Data Structures,Binomial Heap,据我所知,存在一个二项式堆或所谓的可合并堆,用于合并两个堆。我的问题是,如果我将这两个堆复制到一个大数组中,然后执行堆构建过程,而不是动态地将它们合并到一个堆中,那么这是一个好方法还是一个坏方法 因为我不知道如何使用两个堆来创建一个堆,而只使用堆操作。如果这不是一个好方法,请告诉我,或者如果可以,请给我一些链接,其中实现了带有合并操作的二项式堆。如果您仔细想想,通过丢弃其他堆的顺序中嵌入的所有信息来创建一个堆不可能是最优的。最糟糕的情况是,您应该将堆2中的所有项添加到堆1中,而这仅仅是从头创建一
因为我不知道如何使用两个堆来创建一个堆,而只使用堆操作。如果这不是一个好方法,请告诉我,或者如果可以,请给我一些链接,其中实现了带有合并操作的二项式堆。如果您仔细想想,通过丢弃其他堆的顺序中嵌入的所有信息来创建一个堆不可能是最优的。最糟糕的情况是,您应该将堆2中的所有项添加到堆1中,而这仅仅是从头创建一个全新堆的一半工作量
但事实上,你们可以做得更好。合并两个格式良好的堆只需要在另一个堆的树中找到一个根的插入点并将其插入该点即可。不需要进一步的工作,您只做了
ln
工作!有关详细的算法,请参阅。它将解决问题,并为您提供正确的堆-但效率不高
从头开始创建
n
元素的[二进制]堆是O(n)
,而现有的两个二项式堆是O(logn)
合并两个二项式堆的过程与合并排序中的合并操作非常相似。如果不知道合并堆过程是问题所在,那么以下步骤可能会有所帮助
重复步骤1到4,直到其中一个堆为空
Brodal队列和Brodal Okasaki队列(自举斜二项堆)给出了可合并堆的最佳最坏情况渐近界,支持O(1)insert、merge和findMin,以及O(log n)deleteMin。Brodal队列是短暂的,并且支持高效的删除和减少密钥。Brodal Okasaki队列是合流持久性的(实际上纯粹是功能性的),但不支持delete或decreaseKey。不幸的是,Brodal和Okasaki说这两种实现在实践中都是低效的,Brodal认为他的队列太复杂,在任何情况下都不实用
斐波那契堆给出了类似的摊销(但不是最坏情况)界限,在摊销环境中可能更有效、更实用。配对堆是另一个不错的选择:根据Wikipedia的说法,它们的确切界限未知,但它们在实践中表现得非常好。是的,但因为我从未编写过将两个堆合并在一起的程序,所以实现它对我来说是个问题Wikipedia页面上有非常清晰的伪代码——试试看!伪代码是清楚的,但是我如何将它翻译成C++?我很清楚地理解了它的伪代码,很显然,没有人可以为你编写实际代码,因为我们没有你的堆实现来查看。我可以使用标准的程序创建两个堆,你能帮助我合并吗?除非你需要复制数据(例如,因为你使用数组存储)。,此时您不能进行低于
O(n)
的操作(只有较少的比较)。