二项堆实现运行太慢
Binomial heap- implementation running too slow
我正在做一个二项堆的实现。我已经或多或少地修好了,但我不明白为什么它这么慢。这是由于我的方式实现合并堆?作为一系列"if"answers"else if"语句来处理不同的条件?它的另一个问题是deleteTree不起作用。如有任何建议,我将不胜感激。
#include "pqueue-binomial-heap.h"
#include <cmath>
#include <bitset>
using namespace std;
BinomialHeapPQueue::BinomialHeapPQueue() {
carry = NULL;
}
BinomialHeapPQueue::~BinomialHeapPQueue() {
}
string BinomialHeapPQueue::peek() const {
int key = findKey();
node *keynode = heap.get(key);
string nextword = keynode->word;
return nextword;
}
string BinomialHeapPQueue::extractMin() {
int key = findKey();
node *keynode = heap.get(key);
string nextword = keynode->word;
deleteNode(key);
mergeHeaps();
return nextword;
}
void BinomialHeapPQueue::enqueue(const string& elem) {
node *newnode = new node;
newnode->word = elem;
if (heap.size() == 0) {
heap.push_back(NULL);
}
newheap.push_back(newnode);
mergeHeaps();
logSize++;
}
int BinomialHeapPQueue::findKey() const {
int minimum = 0;
string minstring = "zzzzzzzzz";
for (int i = 0; i < heap.size(); i++) {
node *check = heap.get(i);
if (check != NULL) {
string checkstring = check->word;
if (checkstring < minstring) {
minimum = i;
}
}
}
return minimum;
}
void BinomialHeapPQueue::deleteNode(int key) {
node *dnode = heap.get(key);
newheap = dnode->children;
dnode = NULL;
logSize--;
mergeHeaps();
}
void BinomialHeapPQueue::mergeHeaps() {
int i = 0;
while (i < heap.size() && i < newheap.size()) {
node *currentp = heap.get(i);// node from heap
node *currentq = newheap.get(i);// node from the newheap being merged into heap
if (currentp == NULL && currentq == NULL && carry == NULL) {
heap.set(i, NULL);
i++;
}
else if (currentp != NULL && currentq != NULL && carry != NULL) {
heap.set(i, currentp);
carry = mergeTree(carry, currentq);
if (i >= heap.size() - 1) {// extend vector/s if reaching the end and there's still something being carried.
heap.add(NULL);
}
if (i >= newheap.size() -1) {// better to do it this way than make one vector same size as the other- then enqueue gets expensive
newheap.add(NULL);
}
i++;
}
else if (currentp == NULL && currentq == NULL && carry != NULL) {
heap.set(i, carry);
carry = NULL;
//deleteTree(carry); comment out deleteTree because it's not working right now.
//carry = NULL;
i++;
}
else if (currentp != NULL && currentq != NULL && carry == NULL) {
carry = mergeTree(currentp, currentq);
heap.set(i, NULL);
if (i >= heap.size() - 1) {
heap.add(NULL);
}
if (i >= newheap.size() -1) {
newheap.add(NULL);
}
i++;
}
else if (currentp == NULL && currentq != NULL && carry != NULL) {
carry = mergeTree(currentq, carry);
heap.set(i, NULL);
if (i >= heap.size() - 1) {
heap.add(NULL);
}
if (i >= newheap.size() -1) {
newheap.add(NULL);
}
i++;
}
else if (currentp != NULL && currentq == NULL && carry != NULL) {
carry = mergeTree(currentp, carry);
heap.set(i, NULL);
if (i >= heap.size() - 1) {
heap.add(NULL);
}
if (i >= newheap.size() -1) {
newheap.add(NULL);
}
i++;
}
else if (currentp != NULL && currentq == NULL && carry == NULL) {
i++;
}
else if (currentp == NULL && currentq != NULL && carry == NULL) {
heap.set(i, currentq);
i++;
}
}
newheap.clear();
}
void BinomialHeapPQueue::deleteTree(node *tree) {
if (tree == NULL) return;
int size = tree->children.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
node *nexttree = tree->children.get(i);
delete tree;
deleteTree(nexttree);
}
}
return;
}
void BinomialHeapPQueue::deleteVector(Vector<node *> &vec) {
int vecsize = vec.size();
for (int i = 0; i < vecsize; i++) {
if (vec.get(i) != NULL) {
node *startnode = vec.get(i);
deleteTree(startnode);
}
}
vec.clear();
}
BinomialHeapPQueue *BinomialHeapPQueue::merge(BinomialHeapPQueue *one, BinomialHeapPQueue *two) {
return new BinomialHeapPQueue();
}
BinomialHeapPQueue::node *BinomialHeapPQueue::mergeTree(node *currentp, node *currentq) {
string root1 = currentp->word;
string root2 = currentq->word;
if (root1 <= root2) {
return addSubTree(currentp, currentq);
}
else {
return addSubTree(currentq, currentp);
}
}
BinomialHeapPQueue::node *BinomialHeapPQueue::addSubTree(node *root, node *add) {
root->children.add(add);
return root;
}
我认为这是你代码中慢的部分:
while (i < heap.size() && i < newheap.size()) {
node *currentp = heap.get(i);// node from heap
node *currentq = newheap.get(i);//
列表中的get()
不是常数,它在时间复杂度上是线性的。
使用此代码,合并操作的时间复杂度从O(log n)到O(log2 n)。
相关文章:
- 在运行时选择父类的实现
- 如何在 constexpr 函数中实现回退运行时
- 我无法让我的合并排序实现运行
- 使用本机 JNI 静态方法实现C++ Java 运行时错误
- 在C++中使用链表的堆栈实现中,访问结构体headNode成员count和top会导致运行时错误
- C++openssl SHA256运行速度比JDK SHA256实现慢
- 与shared_ptr相比,更小的运行时数据结构和更快的代码可实现独特的_ptr
- 实现上下文切换 - 第二个函数不再运行
- 在运行时选择要使用的 CRTP 实现
- 合并排序的C 实现的运行时错误
- 在已经运行的C 控制台应用程序上实现QT GUI
- llvm错误:重新定位尚未实现!在orcjit或lli中运行RxCpp时
- 二叉搜索树实现C++运行时错误
- 离散小波变换C++实现 - 运行时错误
- Trie 实现运行时错误
- 干净地实现运行时动态链接
- 二项堆实现运行太慢
- 快速排序实现C++运行时错误
- 虚拟函数是在C++中实现运行时多态性的唯一途径吗
- 在这种情况下,哪种设计模式有利于实现运行 tiime 多态性