2014-03-31 48 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++中我們有引用。 –