/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkTreeContainer_hxx #define itkTreeContainer_hxx namespace itk { template TreeContainer::TreeContainer() { m_Root = nullptr; this->SetSubtree(false); m_DefaultChildrenCount = 2; } template TreeContainer::TreeContainer(int dcc) { m_Root = nullptr; this->SetSubtree(false); m_DefaultChildrenCount = dcc; } template TreeContainer::TreeContainer(TreeContainer &) { m_Root = nullptr; this->SetSubtree(false); m_DefaultChildrenCount = 3; } template bool TreeContainer::SetRoot(const TValue element) { m_Root = TreeNodeType::New(); m_Root->Set(element); m_Root->SetParent(nullptr); return true; } template bool TreeContainer::SetRoot(TreeNode * node) { m_Root = node; return true; } template int TreeContainer::Count() const { if (!m_Root) { return 0; } int size = 0; PreOrderTreeIterator it(this, this->m_Root); it.GoToBegin(); while (!it.IsAtEnd()) { ++size; ++it; } return size; } template bool TreeContainer::Swap(IteratorType & v, IteratorType & w) { TreeNode * nv = v.GetNode(); TreeNode * nw = w.GetNode(); if (nv == nullptr || nw == nullptr) { return false; } TreeNode * pv = nv->GetParent(); TreeNode * pw = nw->GetParent(); if (pv == nullptr && pw == nullptr) { return false; } else if (pv == nullptr) { pw->ReplaceChild(nw, nv); m_Root = nw; } else if (pw == nullptr) { pv->ReplaceChild(nv, nw); m_Root = nv; } else { pv->ReplaceChild(nv, nw); pw->ReplaceChild(nw, nv); } nv->SetParent(pw); nw->SetParent(pv); return true; } template bool TreeContainer::Contains(const TValue element) { PreOrderTreeIterator it(this, m_Root); it.GoToBegin(); while (!it.IsAtEnd()) { if (it.Get() == element) { return true; } ++it; } return false; } template bool TreeContainer::operator==(TreeContainer & tree) { PreOrderTreeIterator it(this, m_Root); it.GoToBegin(); PreOrderTreeIterator it2(&tree, tree.GetRoot()); it2.GoToBegin(); while ((!it.IsAtEnd()) && (!it2.IsAtEnd())) { if (it.Get() != it2.Get()) { return false; } ++it; ++it2; } return true; } template bool TreeContainer::IsLeaf(TValue element) { PreOrderTreeIterator it(this, m_Root); it.GoToBegin(); while (!it.IsAtEnd()) { if (it.Get() == element) { if (it.IsLeaf()) { return true; } else { return false; } } } return false; } template bool TreeContainer::IsRoot(TValue element) { PreOrderTreeIterator it(this, m_Root); it.GoToBegin(); while (!it.IsAtEnd()) { if (it.Get() == element) { if (!it.HasParent()) { return true; } else { return false; } } ++it; } return false; } template bool TreeContainer::Clear() { PreOrderTreeIterator it(this, m_Root); bool success = it.Remove(); m_Root = nullptr; return success; } template const TreeNode * TreeContainer::GetNode(TValue val) const { PreOrderTreeIterator it(this, m_Root); it.GoToBegin(); while (!it.IsAtEnd()) { if (it.Get() == val) { return it.GetNode(); } ++it; } return nullptr; } template bool TreeContainer::SetRoot(IteratorType & pos) { if (this->m_SubTree) { return false; } TreeNode * node = pos.GetNode(); if (node == nullptr) { return false; } TreeNode * parent = node->GetParent(); TreeNode * help = nullptr; if (parent == nullptr) { return false; } m_Root = node; node->AddChild(parent); parent->Remove(node); node->SetParent(nullptr); help = parent->GetParent(); parent->SetParent(node); node = parent; while (help != nullptr) { parent = help; help = help->GetParent(); node->AddChild(parent); parent->Remove(node); parent->SetParent(node); node = parent; } return true; } template bool TreeContainer::Add(const TValue child, const TValue parent) { if (!m_Root) { std::cout << "TreeContainer::Add() : The tree is empty" << std::endl; return false; } // Find the first node in the tree that has the parent value PreOrderTreeIterator it(this, m_Root); it.GoToBegin(); while (!it.IsAtEnd()) { if (it.Get() == parent) { it.Add(child); return true; } ++it; } return false; } template void TreeContainer::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Number of objects = " << this->Count() << std::endl; if (this->Count() > 0) { os << indent << "Tree:" << std::endl; // Now prints the tree PreOrderTreeIterator it(this, m_Root); it.GoToBegin(); while (!it.IsAtEnd()) { if (it.GetParent()) { std::cout << it.GetParent()->Get() << " <- "; } std::cout << it.Get() << std::endl; ++it; } } } } // namespace itk #endif