inline void SearchTreeNode::RecalcDepth(BasicSearchTree* tree) { unsigned int curdepth = 0; SearchTreeNode *parent = GetParent(tree); if (parent) curdepth = parent->GetDepth(); m_Depth = curdepth + m_LabelLen; }
void SearchTreeNode::UpdateItems(BasicSearchTree* tree) { SearchTreeNode* parentnode = tree->GetNode(m_Parent,true); if (!parentnode) return; SearchTreeItemsMap newmap; size_t mindepth = parentnode->GetDepth(); SearchTreeItemsMap::iterator i; newmap.clear(); for (i = m_Items.begin();i!=m_Items.end();i++) { if (i->first <= mindepth) parentnode->m_Items[i->first]=i->second; else newmap[i->first]=i->second; } m_Items.clear(); for (i = newmap.begin();i!=newmap.end();i++) m_Items[i->first]=i->second; }
SearchTreePoint BasicSearchTree::AddNode(const wxString& s, nSearchTreeNode nparent) { SearchTreePoint result(0,0); nSearchTreeNode n = 0; bool found = this->FindNode(s,nparent,&result); if (!found) { // Create new node // If necessary, split the edge with a new node 'middle' // If result is exactly a node, middle will be just result.n. nSearchTreeNode middle = SplitBranch(result.n,result.depth); // Now add the node to the middle node SearchTreeNode* newnode; wxString newlabel; if (m_Nodes[middle]->IsLeaf()) { // If it's a leaf node, just extend the label and change // the new node's depth to reflect the changes. n = middle; newnode = m_Nodes[n]; // We take the part of the string that corresponds to node middle. // Since s starts at nparent's depth, we just get the difference and // it will be the position inside the string. newlabel = s.substr(m_Nodes[middle]->GetLabelStartDepth() - m_Nodes[nparent]->GetDepth()); // Modify the leaf node's label to extend the point // Since it's a leaf node, we just concatenate to the current label the missing part. unsigned int oldlen = newnode->GetDepth() - newnode->GetLabelStartDepth(); if (oldlen < newlabel.length()) // Safety check against segfaults { m_Labels[newnode->GetLabelNo()] << newlabel.substr(oldlen); m_Labels[newnode->GetLabelNo()].Shrink(); } newnode->SetLabel(newnode->GetLabelNo(),newnode->GetLabelStart(),newlabel.length()); newnode->RecalcDepth(this); } else { // Get the string's depth. This will be the depth of our new leaf node. size_t newdepth = m_Nodes[nparent]->GetDepth() + s.length(); // start = middle's depth - nparent's depth. newlabel = s.substr(m_Nodes[middle]->GetDepth() - m_Nodes[nparent]->GetDepth()); // Now we create the new label to be accessed by the leaf node "newnode". m_Labels.push_back(newlabel); nSearchTreeLabel nlabel = m_Labels.size() - 1; m_Labels[nlabel].Shrink(); // Finally, we create the new node and link it to "middle". newnode = CreateNode(newdepth,middle,nlabel,0,newlabel.length()); m_Nodes.push_back(newnode); n = m_Nodes.size()-1; m_Nodes[middle]->m_Children[newlabel[0u]]=n; } result.n = n; result.depth = newnode->GetDepth(); } return result; }