2013-04-25 103 views
0

大部分代碼來自Weiss的「C++中的數據結構和算法分析」,在CodeBlock(gnu,gcc)上鍵入代碼後,編譯器報告沒有錯誤,但後來我嘗試創建一個實例並測試它出錯的一些函數。看起來BST()或insert()是錯誤的,因爲程序自運行後立即停止。 會有人幫我找出如何解決這個問題?萬分感謝!!!二進制搜索樹實現(C++)

#include <iostream> 
using namespace std; 
struct TreeNode 
{ 
    int element; 
    TreeNode*left,*right; 
    TreeNode(const int&e,TreeNode*le=NULL,TreeNode*rt=NULL):element(e),left(le),right(rt){}; 
}; 

class BST 
{ 
public: 
    BST(){root=NULL;}; 
    ~BST(){ makeEmpty(root); }; 
// use public member function to call private member functions. 
    void insert(const int & x){ insert(x, root); } 
    void remove(const int & x){ remove(x, root); } 
    TreeNode*findMin() const{ return findMin(root); } 
    bool contain(const int & x) const{ return contain(x,root); } 
    void printNodes() const{ printNodes(root); } 

private: 
    TreeNode*root; 

    void makeEmpty(TreeNode*&); 
    TreeNode* findMin(TreeNode*) const; 
    void insert(const int &, TreeNode*) const; 
    void remove(const int &, TreeNode*) const; 
    bool contain(const int &, TreeNode*) const; 
    void printNodes(TreeNode*) const; 
}; 

void BST::makeEmpty(TreeNode*&t) 
{ 
    if(t!=NULL) 
    { 
     makeEmpty(t->left); 
     makeEmpty(t->right); 
     delete t; 
    } 
    t=NULL; 
} 
TreeNode* BST::findMin(TreeNode*t) const 
{ 
    if(t->left==NULL) return t; 
    return findMin(t->left); 
} 
void BST::insert(const int & x, TreeNode* t) const 
{ 
    if(t==NULL) t=new TreeNode(x,NULL,NULL); 
    else if(x < t->element) insert(x,t->left); 
    else if(x > t->element) insert(x,t->right); 
    else; /// duplicate, do nothing 
} 
void BST::remove(const int & x, TreeNode* t) const 
{ 
    if(t==NULL) return; 
    if(t->element > x) remove(x, t->left); 
    else if(t->element < x) remove(x, t->right); 
    else if(t->left!=NULL && t->right!=NULL) 
    { 
     t->element=findMin(t->right)->element; 
     remove(t->element,t->right); 
    } 
    else 
    { 
     TreeNode*oldNode=t; 
     t=(t->left==NULL)?t->right:t->left; 
     delete oldNode; 
    } 
} 
bool BST::contain(const int & x, TreeNode*t) const 
{ 
    if(t==NULL) return false; 
    else if(x<t->element) return contain(x,t->left); 
    else if(x>t->element) return contain(x,t->right); 
    else return true; 
} 
void BST::printNodes(TreeNode*t) const 
{ 
    if(t==NULL) return; 
    cout<<t->element<<" "; 
    printNodes(t->left); 
    printNodes(t->right); 
    cout<<endl; 
}; 

下面是我寫的測試類BST代碼:

int main() 
{ 
    BST BinarySearchTree; 
    int element,node; 
    for(int i=0; i<5; i++) 
    { 
     cin>>element; 
     BinarySearchTree.insert(element); 
    } 
    BinarySearchTree.printNodes(); 

    cout<<BinarySearchTree.findMin()->element<<endl; 

    cin>>node; 
    if(BinarySearchTree.contain(node)){ cout<<"item "<<node<<" is in BST."<<endl; } 

    BinarySearchTree.remove(node); 
    BinarySearchTree.printNodes(); 
    return 0; 
} 
+3

不知道如何'insert',或'remove'應該是'常量'功能。他們肯定會在某個時候改變這個對象。 您希望您的'TreeNode'像其在'makeEmpty'下定義一樣。 – pickypg 2013-04-25 05:51:00

+1

你可以發佈你測試這個BST的代碼機智嗎?這將幫助我運行,看看有什麼問題。 – Raghuram 2013-04-25 05:57:47

+1

代碼沒有多大意義。我不認爲它可以修復,它需要重寫,並且緩慢。當你不明白自己在做什麼時,從書中輸入很多代碼是不太可能成爲有用的事情。工作更慢。開始學習更容易。 – john 2013-04-25 07:14:49

回答

4

你的類BST只有一個成員變量。 TreeNode*root。 (有沒有問題與)

insertremove功能想必修改BST,所以你需要修改root東西

(和你的編譯器會迅速指出,這些功能不應該const出於同樣的原因。)

1

您在insert()什麼也沒做有根,所以它什麼都不做(除了內存泄漏)。

+0

我確實使用了一個公共成員函數insert()來調用私有函數insert(x,root) – Sol 2013-04-25 10:32:04

+0

,但'root'是通過值傳遞的,所以在私有函數中改變't'除此之外沒有任何效果。 – Elazar 2013-04-25 10:43:14

+0

嗯,我已經改變了參數Treenode *在私人插入()Treenode *&,猜這工作了嗎? – Sol 2013-04-26 06:16:16

2
void BST::makeEmpty(TreeNode*&t) 
{ 
    if(t==NULL) 
    { 
     makeEmpty(t->left); 
     makeEmpty(t->right); 
     delete t; 
    } 
    t=NULL; 
} 

這段代碼是錯誤的,如果t爲NULL,那麼你做t-> left和t-> right。這被稱爲取消引用空指針,並可能使您的程序立即崩潰。

這應該是

void BST::makeEmpty(TreeNode*&t) 
{ 
    if (t!=NULL) 
    { 
     makeEmpty(t->left); 
     makeEmpty(t->right); 
     delete t; 
    } 
    t=NULL; 
} 
+0

呃...這是一個打字錯誤,對不起,我沒有注意到。 – Sol 2013-04-25 10:22:20