2014-03-31 36 views
0

这是我的代码。使用二进制搜索树时无效的内存访问

#include<iostream> 

template<class Elem> 
class BinNode 
{ 
public: 
    virtual Elem& getVal() = 0; 
    virtual void setVal(const Elem&) = 0; 
    virtual BinNode* left() = 0; 
    virtual BinNode* right() = 0; 
    virtual void setLeft(BinNode*) = 0; 
    virtual void setRight(BinNode*) = 0; 
    virtual bool isLeaf() = 0; 
};//abstract class 

template<class Elem> 
class BinNodePtr:public BinNode<Elem> 
{ 
public: 
    Elem val; 
    BinNodePtr* lc; 
    BinNodePtr* rc; 
    BinNodePtr() 
    { 
     lc = rc = NULL; 
    } 
    ~BinNodePtr() 
    { 
     delete lc; 
     delete rc; 
    } 
    void setVal(const Elem& e) 
    { 
     val = e; 
    } 
    Elem& getVal() 
    { 
     return this->val; 
    } 
    void setLeft(BinNode<Elem>* e) 
    { 
      lc = (BinNodePtr<Elem>*)e; 
    } 
    void setRight(BinNode<Elem>* e) 
    { 
     rc = (BinNodePtr<Elem>*)e; 
    } 
    bool isLeaf() 
    { 
     if(this->lc == NULL && this->rc == NULL) 
     return true; 
     return false; 
    } 
    BinNodePtr<Elem>* left() 
    { 
     return lc; 
    } 
    BinNodePtr<Elem>* right() 
    { 
     return rc; 
    } 
}; 

template<class Elem> 
class BST 
{ 
public: 
    BinNodePtr<Elem> *root; 
    int nodenum; 
    void deleteElem(BinNodePtr<Elem>* start); 
    void midorder(BinNodePtr<Elem>* start); 
public: 
    BST() 
    { 
     root = NULL; 
     nodenum = 0; 
    } 
    ~BST() 
    { 
     deleteElem(root); 
    } 
    bool insert(BinNodePtr<Elem>* ptr,const Elem &e); 
    BinNodePtr<Elem>* getRoot(){return root;} 
}; 
template<class Elem> 
void BST<Elem>::deleteElem(BinNodePtr<Elem>* start) 
{ 
    BinNodePtr<Elem>* temp =(BinNodePtr<Elem>*) start; 
    if(temp == NULL) return; 
    deleteElem((BinNodePtr<Elem>*)temp->left()); 
    deleteElem((BinNodePtr<Elem>*)temp->right()); 
    delete temp; 
} 

template<class Elem> 
void BST<Elem>::midorder(BinNodePtr<Elem> *start) 
{ 
    if(start == NULL) return; 
    midorder(start->lc); 
    printf("%d ",start->getVal()); 
    midorder(start->rc); 
} 

template<class Elem> 
bool BST<Elem>::insert(BinNodePtr<Elem>*ptr,const Elem &e) 
{ 
    if(ptr == NULL) 
    { 
     ptr = new BinNodePtr<Elem>; 
     ptr->lc = NULL; 
     ptr->rc = NULL; 
     ptr->val = e; 
     return true; 
    } 
    else 
    { 
     if(ptr->val < e || ptr->val == e) 
      { 
     ptr = ptr->right(); 
     insert(ptr->rc,e); 
     } 
     else 
      { 
     ptr = ptr->left(); 
     insert(ptr->lc,e); 
      } 
    } 
    return false; 
} 

int main() 
{ 
    BST<int> myBST; 
    myBST.insert(myBST.root,10); 
    myBST.insert(myBST.root,20); 
    myBST.insert(myBST.root,5); 
    myBST.insert(myBST.root,30); 
    printf("%d",myBST.getRoot()->getVal()); 

    system("pause"); 
    return 0; 
} 

有未在我的program.I使用的一些功能集中在“插入”功能。当我调试这个程序在printf("%d",myBST.getRoot()->getVal());坏了说:“无效的内存访问”,为什么和如何解决这个问题?

+0

我认为在我的函数“插入”中也存在一些错误。我认为甚至没有插入一个数字,但我不知道如何解决这个问题。:( – BecomeBetter

+0

你应该如此友好以减少代码尽可能保留手头的问题?人们不太可能通读全部内容,特别是如果你自称其中存在未使用的功能,请提供[SSCCE](http://sscce.org)。 )。如果你没有权限编辑你的问题,请随意创建一个新的并删除这个。 –

+0

什么是二元_research_树?你的意思是搜索吗? – mjs

回答

0

您必须记住,在C++参数中默认传值,这意味着它们的值是复制到被调用函数的参数。当您更改函数中的参数时,您只更改其本地副本,副本的更改将传播给调用方。

要更改的参数在调用者,你必须通过引用传递它,就像

bool insert(BinNodePtr<Elem>*& ptr,const Elem& e); 

这将使ptr参数指针引用,所以改变它会传播给调用者。

0

如果要更改插入功能的PTR的说法,你应该通过它的地址,像这样:

template<class Elem> 
bool BST<Elem>::insert(BinNodePtr<Elem>**ptr,const Elem &e) 

或传递一个参考吧。

+0

不,不,不是的,这是旧的C方式,在C++中我们有引用。 –