C ++:二进制搜索树分段错误

时间:2015-11-06 03:31:59

标签: c++ recursion tree segmentation-fault binary-search-tree

我正在制作一个二叉搜索树,用树中填充的对象包含从文本文件读入的字符串code和int quantity。另一个函数通过读取另一个文本文件来更新树,搜索该对象,更新它quantity,如果quantity达到0,则删除该节点。

我的程序最多可以运行Update.txt文件中需要搜索和更新的第8个对象。在我的调试器中,我在BSTree.template的第113行收到了段错误,其中显示为:else if (q_ptr->data() == obj)。这相当令人困惑,因为之前的if语句会询问q_ptrNULL。鉴于它移动到else,这只能意味着它包含数据。

以下是位于DBInterface.cpp的文件功能的更新:

    void DBInterface::updateFromFile(string f_Name) 
{
    ifstream file (f_Name.c_str());
    string line;


    if (file.is_open())
    {
        std::getline(file, line);
        while (std::getline (file, line))
        {
            std::istringstream iss (line);
            int q=0;
            int pos=0;
            pos = line.find('\t',0); //find position of blank space
            string tmp_str = line.substr(0,pos); //create a substring
            string tmp_str1 = line.substr((pos+1), string::npos);
            stringstream ss (tmp_str1);
            ss >> q;
            MechPart tmp_mp;
            MechPart currentQuantity;
            tmp_mp.set_code(tmp_str); //set code
            tmp_mp.set_quantity(q);
            cout << "Current data: " << tmp_mp.get_code() << " | " << tmp_mp.get_quantity() << endl;
            currentQuantity = tree.quantitySearch(tree.getRoot(), tmp_mp);
            int new_quantity = currentQuantity.get_quantity();
            tmp_mp.set_quantity(new_quantity + q);

            BTNode<MechPart>* updated_ptr = tree.update(tree.getRoot(), tmp_mp);
            if (updated_ptr->data() <= 0)
            {
                tree.remove(updated_ptr);
            }


        }
    }
    file.close();

此搜索函数传入根节点和Update.txt文件中的对象,然后在树中找到对象的匹配项,然后返回该对象以从中提取其当前quantity ,因此可以使用新值更新。

    template <typename Item>
Item BSTree<Item>::quantitySearch(BTNode<Item>* q_ptr, Item obj)
{
    if (q_ptr == NULL)
    {
        //POINTER IS NULL
        return obj;
    }
    else if (q_ptr->data() == obj)
    {
        return q_ptr->data();
    }

    else if (obj > q_ptr->data()) 
    { //WORK ON RIGHT SIDE
        return quantitySearch(q_ptr->get_right(), obj);
    }
    else
    {
    //work on left side
        return quantitySearch(q_ptr->get_left(), obj);

    }

}

以下是BSTree<Item>::remove

中的BSTree.template函数
template <typename Item>
void BSTree<Item>::remove(BTNode<Item>* rptr)
{
 //Locate the element
bool found = false;
if(root==NULL)
{
    //cout<<" This Tree is empty "<<endl;
    return;
}

BTNode<Item>* curr;
BTNode<Item>* parent;
curr = root;

while(curr != NULL)
{
     if(curr->data() == rptr->data())
     {
        found = true;
        break;
     }
     else
     {
         parent = curr;
         if(rptr->data() > curr->data())
         {
            curr = curr->get_right(); //if Item's data is greater than curr's data, point to the parent's right child
         }
         else 
         {
            curr = curr->get_left(); //else point to left branch
         }
     }
}
if(!found)
     {
    //cout<<" Data not found! "<<endl;
    return;
}


// Node with single child
if((curr->get_left() == NULL && curr->get_right() != NULL)|| (curr->get_left() != NULL
&& curr->get_right() == NULL))
{
   if(curr->get_left() == NULL && curr->get_right() != NULL) 
//IF the right child is not null, left child NULL
       {
           if(parent->get_left() == curr)
           {
            parent->set_left(curr->get_right());
            delete curr;
           }
           else
           {
            parent->set_right(curr->get_right());
            delete curr;
           }
       }
       else 
//  1 -- 0 Left child present, right child NULL
       {
          if(parent->get_left() == curr)
           {
             parent->set_left(curr->get_left());
             delete curr;
           }
           else
           {
             parent->set_right(curr->get_left());
             delete curr;
           }
       }
     return;
    }

//leaf node
         if( curr->get_left() == NULL && curr->get_right() == NULL)
    {
        if(parent->get_left() == curr)
        {
            parent->set_left(NULL);
        }
        else parent->set_right(NULL);
        delete curr;
        return;
    }


//Node with 2 children
// replace node with smallest value in right subtree
    if (curr->get_left() != NULL && curr->get_right() != NULL)
    {
        BTNode<Item>* chkr;
        chkr = curr->get_right();
        if((chkr->get_left() == NULL) && (chkr->get_right() == NULL))
        {
            curr = chkr;
            delete chkr;
            curr->set_right(NULL);
        }
        else // right child has children
        {
            //if the node's right child has a left child
            // Move all the way down left to locate smallest element

            if((curr->get_right())->get_left() != NULL)
            {
                BTNode<Item>* lcurr;
                BTNode<Item>* lcurrp;
                lcurrp = curr->get_right();
                lcurr = (curr->get_right())->get_left();
                while(lcurr->get_left() != NULL)
                {
                   lcurrp = lcurr;
                   lcurr = lcurr->get_left();
                }
        curr->set_data(lcurr->data());
                delete lcurr;
                lcurrp->set_left(NULL);
           }
           else
           {
                BTNode<Item>* tmp;
                tmp = curr->get_right();
                curr->set_data(tmp->data());
                curr->set_right(tmp->get_right());
                delete tmp;
           }

        }
         return;
    }

}

以下是BSTree<Item>::update函数的代码:

    template <typename Item>
BTNode<Item>* BSTree<Item>::update(BTNode<Item>* ptr, Item itm)
{
    if (ptr == NULL)
    {
        //POINTER IS NULL
    }
    else if (ptr->data() == itm)
    {
        ptr->set_data(itm);

    }

    else if (itm > ptr->data()) 
    { //WORK ON RIGHT SIDE
        return update(ptr->get_right(), itm);
    }
    else
    {
    //work on left side
        return update(ptr->get_left(), itm);

    }
    return ptr;

}

编辑:为插入功能添加了代码

    template <typename Item>
void BSTree<Item>::insert(BTNode<Item>* node, Item it) {


    if (root == NULL)
    {
    root = new BTNode<Item>(it);
    }
    else if (node == NULL)
    {
        node = new BTNode<Item>(it);
    }
    else if (it > node->data()) 
    {
        if (node->get_right() == NULL) 
        {
            BTNode<Item>* tmp = node->get_right();
            tmp = new BTNode<Item>(it);
            node->set_right(tmp);

        }
        else 
        {
            insert(node->get_right(), it);
        }
    }
    else if (node->get_left() == NULL) 
    {
        //work on left side
            BTNode<Item>* tmp = node->get_left();
            tmp = new BTNode<Item>(it);
            node->set_left(tmp);

    }
    else 
    {
        insert (node->get_left(), it);
    }

}

这是调用文件并插入树中的函数:

    void DBInterface::readFromFile(string fName) {
    ifstream file (fName.c_str());

    string line;

    MechPart mechP;
    if (file.is_open())
    {
        std::getline (file, line);
        while (std::getline (file, line))
        {
            //bool test= tree.getEmpty();
            std::istringstream iss (line);
            int i=0;


            int stop;
            stop = line.find('\t',0); //find position of blank space
            string tmp_str = line.substr(0,stop); //create a substring
            string tmp_str1 = line.substr((stop+1), string::npos);
            stringstream ss (tmp_str1);
            ss >> i;
            mechP.set_quantity(i); //set quantity

            mechP.set_code(tmp_str); //set code
            tree.insertRoot(mechP); //insert into the tree
            cout << "Current line: " << tmp_str << " Current quantity: " << i << endl;
        }

    }
    file.close();
}

编辑2:BTNode的构造函数

    template <typename Object>
BTNode<Object>::BTNode() { //default constructor
    left= NULL;
    right= NULL;
    parent= NULL;



}
template <typename Object>
BTNode<Object>::BTNode(Object initial_val) { //constructor with parameters
    item = initial_val;
    left = NULL;
    right = NULL;
    parent = NULL;
}

0 个答案:

没有答案