左堆在c++中的实现
leftist heap implementation in c++
下午好,我正在尝试实现左堆这是我的头文件和源文件用于头文件
#include<iostream>
template<class comparable>
class leftistheap;
template<class comparable>
class leftistnode
{
comparable element;
leftistnode *left;
leftistnode *right;
int npl;
leftistnode(const comparable &theelement,leftistnode *lt=NULL,leftistnode *rt=NULL,int np=0):element(thelement),left(lt),right(rt),npl(np){}
friend class leftistheap<comparable>;
};
template<class comparable>
class leftistheap
{
public:
leftistheap();
leftistheap (const leftistheap &rhs);
~leftistheap();
bool isempthy()const ;
bool isfull() const;
const comparable &findmin() const;
void insert(const comparable &x);
void deletemin();
void deletemin(comparable &minitem);
void makeempthy();
void merge(leftistheap &rhs);
const leftistheap & operator=(const leftistheap &rhs);
private:
leftistnode<comparable>*root;
leftistnode<comparable>*merge(leftistnode<comparable>*h1,leftistnode<comparable>*h2)const;
leftistnode<comparable> * merge1( leftistnode<comparable> *h1,
leftistnode<comparable> *h2 ) const;
void swapchildren( leftistnode<comparable> * t ) const;
void reclaimmemory( leftistnode<comparable> * t ) const;
leftistnode<comparable> * clone( leftistnode<comparable> *t ) const;
};
和源文件
#include<iostream>
#include "leftist.h"
using namespace std;
template<class comparable>
leftistheap<comparable>::leftistheap()
{
root=NULL;
}
template<class comparable>
leftistheap<comparable>::leftistheap(const leftistheap<comparable>&rhs)
{
root=NULL;
*this=rhs;
}
template<class comparable>
leftistheap<comparable>::~leftistheap()
{
makeempthy();
}
template<class comparable>
void leftistheap<comparable>::merge(leftistheap &rhs)
{
if(this==&rhs)
return;
root=merge(root,rhs.root);
rhs.root=NULL;
}
template<class comparable>
leftistnode<comparable>*leftistheap<comparable>::merge(leftistnode <comparable>*h1,leftistnode<comparable>*h2)const
{
if(h1==NULL)
return h2;
if(h2==NULL)
return h1;
if(h1->element<h2->element)
return merge1(h1,h2);
else
return merge1(h2,h1);
}
template<class comparable>
leftistnode<comparable>*leftistheap<comparable>::merge1(leftistnode<comparable>*h1,leftistnode<comparable>*h2)const
{
if(h1->left==NULL)
h1->left=h2;
else
{
h1->right=merge(h1->right,h2);
if(h1->left->npl<h1->right->npl)
swapchildren(h1);
h1->npl=h1->right->npl+1;
}
return h1;
}
template<class comparable>
void leftistheap<comparable>::swapchildren(leftistnode<comparable>*t)const
{
leftistnode<comparable> *temp=t->left;
t->left=t->right;
t->right=emp;
}
template<class comparable>
void leftistheap<comparable>::insert(const comparable &x)
{
root=merge(new leftistnode<comparable>(x),root);
}
template<class comparable>
const comparable &leftistheap<comparable>::findmin()const
{
if(isempty())
throw Underflow();
return root->element;
}
template<class comparable>
void leftistheap<comparable>::deletemin()
{
if(isempty())
throw Underflow();
leftistnode<comparable>*oldroot=root;
root=merge(root->left,root->right);
delete oldroot;
}
template<class comparable>
void leftistheap<comparable>::deletemin(comparable & minitem)
{
minitem=findmin();
deletemin();
}
template<class comparable>
bool leftistheap<comparable>::isempthy() const
{
return root=NULL;
}
template<class comparable>
bool leftistheap<comparable>::isfull( ) const
{
return false;
}
template <class comparable>
void leftistheap<comparable>::makeempthy()
{
reclaimmemory( root );
root = NULL;
}
template<class comparable>
const leftistheap<comparable>& leftistheap<comparable >::operator=(const leftistheap<comparable>& rhs)
{
if(this != &rhs)
{
makeempthy();
root=clone(rhs.root);
}
return *this;
}
template<class comparable>
void leftistheap<comparable>::reclaimmemory(leftistnode<comparable>*t) const
{
if(t!=NULL)
{
reclaimmemory(t->left);
reclaimmemory(t->right);
delete t;
}
}
template<class comparable>
leftistnode<comparable>*leftistheap<comparable>::clone(leftistnode<comparable> *t)const
{
if(t==NULL)
return NULL;
else
return new leftistnode<comparable>( t->element, clone( t->left ),
clone( t->right ), t->npl );
}
int main()
{
int numitems=100;
leftistheap<int>h;
leftistheap<int>h1;
leftistheap<int>h2;
int i=37;
for(i=37;i!=0;i=(i+37)%numitems)
if(i%2==0)
h1.insert(i);
else
h.insert(i);
h.merge(h1);
h2=h;
for( i = 1; i < numitems; i++ )
{
int x;
h2.deletemin( x );
if( x != i )
cout << "Oops! " << i << endl;
}
if (! h1.isempthy( ) )
cout << "Oops! h1 should have been empty!" << endl;
return 0;
}
但是我得到了这些错误,请帮助我为什么这些错误?我已经将函数声明为const,但我并没有修改它,那么问题出在哪里呢?我只是想定义这些函数,这就是我习惯做的,同样的问题也存在于root,为什么编译器说,我试图改变root的值?isempthy()函数只是检查是否(root==NULL),但它不会改变它的值,所以我真的很困惑,如果我删除const关键字,我的代码会编译吗?它不会改变代码的主要行为吗?我是新来的,很抱歉发布了这么大的代码,但为了让代码更清晰,我想把标题和源文件放在一起为你们简化任务,请帮帮我,伙计们,我很高兴有这么好的网站。如果能得到你们的帮助,我会很高兴的错误为:
2010projectsleftist_heapleftist_heapleftist_heap.cpp(115): error C3490: 'root' cannot be modified because it is being accessed through a const object
1> 2010projectsleftist_heapleftist_heapleftist_heap.cpp(112) : while compiling class template member function 'bool leftistheap<comparable>::isempthy(void) const'
1> with
1> [
1> comparable=int
1> ]
1> 2010projectsleftist_heapleftist_heapleftist_heap.cpp(169) : see reference to class template instantiation 'leftistheap<comparable>' being compiled
1> with
1> [
1> comparable=int
1> ]
1>2010projectsleftist_heapleftist_heapleftist_heap.cpp(115): warning C4800: 'leftistnode<comparable> *const ' : forcing value to bool 'true' or 'false' (performance warning)
1> with
1> [
1> comparable=int
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
将isempty
成员函数的实现更改为(逻辑是检查树是否为空):
template<class comparable>
bool leftistheap<comparable>::isempthy() const
{
return root==NULL;
}
template<class comparable>
bool leftistheap<comparable>::isempthy() const
{
return root=NULL;
}
这就是您的问题——方法后的const意味着它不会修改对象的状态,而是通过更改根的值来修改。
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- std::random_device是如何实现的