我有一個包含節點和答案的決策樹,將我們引向另一個節點。答案以“:”開頭,其余的是節點。

我必須執行一個從特定節點洗掉子樹的函式。例如,如果我想洗掉節點“品牌?”,我希望之后樹將從car-color?到blue-is-beautiful
我沒有以正確的方式成功洗掉此操作,因為我認為我還必須洗掉答案red,但不知道該怎么做。
class Answer
{
public:
string ans;
Node* son;
Answer(string s, Node* p) { ans = s; son = p; }
};
class Node
{
public:
Node(string v) { isLeaf = true; value = v; }
list<Answer*> answersList;
string value;
bool isLeaf;
};
void Tree::del(Node* t)
{
if (t->isLeaf)
return;
for (list<Answer*>::iterator it = t->answersList.begin(); it != t->answersList.end(); it )
{
del((*it)->son);
delete((*it));
*it = NULL;
}
if (t)
{
delete t;
t = NULL;
}
}
uj5u.com熱心網友回復:
現在已經了解了問題(高度限制性的要求以及導致您的代碼失敗的原因),我現在為您提供了答案。
問題是,您需要從存盤它的集合中洗掉已洗掉的節點。為此,您需要使用搜索的替代版本來檢測哪個子節點具有您正在尋找的值。
由于“不添加任何附加功能”的要求,有兩種方法可以做到這一點。
一種是使用匿名函式進行遞回,另一種是“在潛入之前檢查孩子”。
以下代碼片段使用 DIY-Lambda-Functor,它采用遞回方法。
void Tree::deletefromNode(string val)
{
bool didFindValue = false;
std::function<bool (Node *, const string &)> functor;
class Functor
{
public:
Functor(Tree *owner, bool &didFindValue) : owner(owner), didFindValue(didFindValue)
{
}
bool deleteFromNode(Node *node, const string &value)
{
bool foundMatch = false;
if (node)
{
foundMatch = (node->value == value);
if (!foundMatch)
{
for (list<Answer*>::iterator it = node->answersList.begin(); it != node->answersList.end();)
{
Node *childNode = (*it)->son;
if (deleteFromNode(childNode, value))
{
owner->del(childNode);
it = node->answersList.erase(it);
didFindValue = true;
}
else
it ;
}
}
}
return foundMatch;
}
private:
Tree *owner;
bool &didFindValue;
};
Functor(this, didFindValue).deleteFromNode(root, val);
if (didFindValue)
cout << "Value not found" << endl;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/326800.html
