00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkPostOrderTreeIterator_h
00018 #define __itkPostOrderTreeIterator_h
00019
00020 #include <itkTreeIteratorBase.h>
00021
00022 namespace itk{
00023
00024 template <class TTreeType>
00025 class PostOrderTreeIterator : public TreeIteratorBase<TTreeType>
00026 {
00027 public:
00028
00030 typedef TreeIteratorBase<TTreeType> Superclass;
00031 typedef TTreeType TreeType;
00032 typedef typename TTreeType::ValueType ValueType;
00033 typedef typename Superclass::TreeNodeType TreeNodeType;
00034
00036 PostOrderTreeIterator(TreeType* tree);
00037
00039 int GetType() const;
00041 TreeIteratorBase<TTreeType>* Clone();
00042
00043 protected:
00045 const ValueType& Next();
00047 bool HasNext() const;
00048
00049 protected:
00050
00051 const TreeNodeType* FindNextNode() const;
00052 const TreeNodeType* FindMostRightLeaf(TreeNodeType* node) const;
00053 const TreeNodeType* FindSister(TreeNodeType* node) const;
00054
00055 };
00056
00058 template <class TTreeType>
00059 PostOrderTreeIterator<TTreeType>::PostOrderTreeIterator( TTreeType* tree)
00060 :TreeIteratorBase<TTreeType>(tree,NULL)
00061 {
00062 this->m_Position = const_cast<TreeNode<ValueType>*>(tree->GetRoot());
00063
00064 if ( this->m_Position == NULL )
00065 {
00066 this->m_Begin = NULL;
00067 }
00068 else
00069 {
00070 this->m_Position =const_cast<TreeNodeType* >(FindMostRightLeaf(this->m_Position));
00071 this->m_Begin = this->m_Position;
00072 }
00073 }
00074
00075
00077 template <class TTreeType>
00078 int
00079 PostOrderTreeIterator<TTreeType>::GetType() const
00080 {
00081 return TreeIteratorBase<TTreeType>::POSTORDER;
00082 }
00083
00084
00086 template <class TTreeType>
00087 bool
00088 PostOrderTreeIterator<TTreeType>::HasNext() const
00089 {
00090 if(const_cast<TreeNodeType* >(FindNextNode()) != NULL)
00091 {
00092 return true;
00093 }
00094 return false;
00095 }
00096
00098 template <class TTreeType>
00099 const typename PostOrderTreeIterator<TTreeType>::ValueType&
00100 PostOrderTreeIterator<TTreeType>::Next()
00101 {
00102 this->m_Position = const_cast<TreeNodeType*>(FindNextNode());
00103 return this->m_Position->Get();
00104 }
00105
00107 template <class TTreeType>
00108 const typename PostOrderTreeIterator<TTreeType>::TreeNodeType*
00109 PostOrderTreeIterator<TTreeType>::FindNextNode() const
00110 {
00111 if ( this->m_Position == NULL || this->m_Position == this->m_Root )
00112 {
00113 return NULL;
00114 }
00115 TreeNodeType* sister = const_cast<TreeNodeType*>(FindSister( this->m_Position ));
00116
00117 if ( sister != NULL )
00118 {
00119 return FindMostRightLeaf( sister );
00120 }
00121
00122 return this->m_Position->GetParent();
00123 }
00124
00125
00127 template <class TTreeType>
00128 const typename PostOrderTreeIterator<TTreeType>::TreeNodeType*
00129 PostOrderTreeIterator<TTreeType>::FindSister( TreeNodeType* node ) const
00130 {
00131 if ( !node->HasParent() )
00132 {
00133 return NULL;
00134 }
00135
00136 TreeNodeType* parent = node->GetParent();
00137 int childPosition = parent->ChildPosition( node );
00138 int lastChildPosition = parent->CountChildren() - 1;
00139
00140 while ( childPosition < lastChildPosition )
00141 {
00142 TreeNodeType* sister = parent->GetChild( childPosition + 1);
00143
00144 if ( sister != NULL )
00145 {
00146 return sister;
00147 }
00148 childPosition++;
00149 }
00150 return NULL;
00151 }
00152
00154 template <class TTreeType>
00155 const typename PostOrderTreeIterator<TTreeType>::TreeNodeType*
00156 PostOrderTreeIterator<TTreeType>::FindMostRightLeaf(TreeNodeType* node) const
00157 {
00158 while ( node->HasChildren() )
00159 {
00160 TreeNodeType* helpNode;
00161 int childCount = node->CountChildren();
00162 int i = 0;
00163
00164 do
00165 {
00166 helpNode = node->GetChild( i );
00167 i++;
00168 } while ( helpNode == NULL && i < childCount );
00169
00170 if ( helpNode == NULL )
00171 {
00172 return node;
00173 }
00174 node = helpNode;
00175 }
00176 return node;
00177 }
00178
00180 template <class TTreeType>
00181 TreeIteratorBase<TTreeType>* PostOrderTreeIterator<TTreeType>::Clone()
00182 {
00183 PostOrderTreeIterator<TTreeType>* clone = new PostOrderTreeIterator<TTreeType>( const_cast<TTreeType*>(this->m_Tree) );
00184 *clone = *this;
00185 return clone;
00186 }
00187
00188 }
00189
00190 #endif
00191