我正在制作一个二叉搜索树,用树中填充的对象包含从文本文件读入的字符串code
和int quantity
。另一个函数通过读取另一个文本文件来更新树,搜索该对象,更新它quantity
,如果quantity
达到0,则删除该节点。
我的程序最多可以运行Update.txt文件中需要搜索和更新的第8个对象。在我的调试器中,我在BSTree.template
的第113行收到了段错误,其中显示为:else if (q_ptr->data() == obj)
。这相当令人困惑,因为之前的if
语句会询问q_ptr
是NULL
。鉴于它移动到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;
}