Import Geant4 8.1.0 source tree
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Troy A. Johnson, tajohnson@ieee.org
|
||||
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,37 @@
|
||||
Version 0.5.0, 1/2/2006
|
||||
- Realized that assignment to *i for const_iterators was
|
||||
being allowed. Fixed.
|
||||
- Forced instantiation of whole template and caught
|
||||
several typos (iterator in place of const_iterator, etc.)
|
||||
- Can now find the size of subtrees using a size() method
|
||||
of iterator or const_iterator
|
||||
- i += n for sibling_iterators
|
||||
- Added range constructor to build n-ary trees
|
||||
- Allow conversion from iterator to const_iterator
|
||||
- Added height() and height_leftmost() tree methods
|
||||
- First serious attempt at pointer specialization. It is
|
||||
disabled by default because it is incomplete and programs
|
||||
with only a few types of pointer trees will get larger.
|
||||
If you have many different types of trees, then the program
|
||||
size should increase less with specialization enabled.
|
||||
Suggestions on the best way to implement specialization
|
||||
are welcome.
|
||||
|
||||
Version 0.2.1, 12/17/2005
|
||||
- Compatible with gcc 4.0
|
||||
- Pruning for const_preorder_iterator
|
||||
- Added depth counter for iterators
|
||||
- Added addition operator to sibling_iterators so that you can
|
||||
do stuff like j = i + 1.
|
||||
|
||||
Version 0.2.0, 04/05/2005
|
||||
- Now compatible with gcc 3.4
|
||||
- In between 0.1.0 and 0.2.0, the tree class saw
|
||||
extensive use representing parse trees and various
|
||||
other tree structures in my own programs. Remaining
|
||||
bugs are likely in methods I don't use very often
|
||||
but provided because they seemed useful.
|
||||
|
||||
Version 0.1.0, 07/18/2003
|
||||
- very general tree template
|
||||
- STL compatible
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
class bfs_iterator : public virtual iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
std::list<tree_node<N>*> queue;
|
||||
|
||||
typedef bool (*PruningPredicate)(const iterator& iter);
|
||||
PruningPredicate prune_pred;
|
||||
|
||||
explicit bfs_iterator(tree_node<N>* current) : iterator(current), prune_pred(NULL) { }
|
||||
|
||||
public:
|
||||
|
||||
bfs_iterator(void) : prune_pred(NULL) { }
|
||||
bfs_iterator(const iterator& iter) : iterator(iter), prune_pred(NULL) { }
|
||||
|
||||
bfs_iterator endBfs(void) { return bfs_iterator(NULL); }
|
||||
|
||||
bfs_iterator& operator ++ (void)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
if (prune_pred == NULL || !prune_pred(*this))
|
||||
{
|
||||
for (tree_node<N>* p = current->first_child;
|
||||
p != NULL; p = p->next_sibling)
|
||||
{
|
||||
queue.push_front(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (queue.empty())
|
||||
{
|
||||
current = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = queue.back();
|
||||
queue.pop_back();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** When the iterator points to a node, and the pruning predicate
|
||||
* returns true, the children of the node are not added to the BFS
|
||||
* queue. True means prune everything beneath the node passed
|
||||
* to the predicate. A NULL predicate disables pruning. */
|
||||
void pruneOn(PruningPredicate prune_pred)
|
||||
{
|
||||
this->prune_pred = prune_pred;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
class const_bfs_iterator : public virtual const_iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
std::list<tree_node<N>*> queue;
|
||||
|
||||
explicit const_bfs_iterator(tree_node<N>* current) : const_iterator(current) { }
|
||||
|
||||
public:
|
||||
|
||||
const_bfs_iterator(void) { }
|
||||
const_bfs_iterator(const const_iterator& iter) : const_iterator(iter) { }
|
||||
|
||||
const_bfs_iterator endBfs(void) const { return const_bfs_iterator(NULL); }
|
||||
|
||||
const_bfs_iterator& operator ++ (void)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
for (tree_node<N>* p = current->first_child;
|
||||
p != NULL; p = p->next_sibling)
|
||||
{
|
||||
queue.push_front(p);
|
||||
}
|
||||
|
||||
if (queue.empty())
|
||||
{
|
||||
current = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = queue.back();
|
||||
queue.pop_back();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
template<class N>
|
||||
size_t tree<N>::const_iterator::size(void) const
|
||||
{
|
||||
size_t s = 1;
|
||||
|
||||
for (typename tree<N>::const_sibling_iterator i(beginChildren());
|
||||
i != endChildren(); ++i)
|
||||
{
|
||||
s += i.size();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** An iterator that can be used to inspect the tree but not modify it.
|
||||
*/
|
||||
class const_iterator : public tree_iterator<N, const N&, const N*>
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
/* allows iterator to call the protected constructor below */
|
||||
friend tree<N>::iterator::operator const_iterator() const;
|
||||
|
||||
private:
|
||||
|
||||
/* this typedef is very convenient and allows Java-like code */
|
||||
typedef tree_iterator<N, const N&, const N*> super;
|
||||
|
||||
protected:
|
||||
|
||||
const_iterator(tree_node<N>* current) : super(current) { }
|
||||
|
||||
public:
|
||||
|
||||
const_iterator(void) { }
|
||||
const_iterator(const const_iterator& iter) : super(iter) { }
|
||||
|
||||
typename super::reference
|
||||
operator * (void) const { return this->current->data; }
|
||||
|
||||
typename super::pointer
|
||||
operator -> (void) const { return &(this->current->data); }
|
||||
|
||||
const_sibling_iterator beginChildren(void) const
|
||||
{ return const_sibling_iterator(const_iterator(this->current->first_child)); }
|
||||
|
||||
const_sibling_iterator endChildren(void) const
|
||||
{ return const_sibling_iterator(const_iterator(NULL)); }
|
||||
|
||||
const_iterator parent(void) const
|
||||
{ return this->current->parent; }
|
||||
|
||||
/** Determines the size of the subtree below and including this position.
|
||||
*
|
||||
* @return The size of this subtree.
|
||||
*/
|
||||
size_t size(void) const;
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** Iterates through the graph visiting parents after children and does not allow changes.
|
||||
*/
|
||||
class const_postorder_iterator : public virtual const_iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
explicit const_postorder_iterator(tree_node<N>* current) : const_iterator(current) { }
|
||||
|
||||
public:
|
||||
|
||||
const_postorder_iterator(void) { }
|
||||
const_postorder_iterator(const const_iterator& iter) : const_iterator(iter) { }
|
||||
|
||||
const_postorder_iterator& operator++(void)
|
||||
{
|
||||
post_inc(this->current, this->iter_depth);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_postorder_iterator& operator--(void)
|
||||
{
|
||||
post_dec(this->current, this->iter_depth);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** Iterates through the graph visiting parents before children and does not allow changes.
|
||||
*/
|
||||
class const_preorder_iterator : public virtual const_iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
explicit const_preorder_iterator(tree_node<N>* current) : const_iterator(current) { }
|
||||
|
||||
public:
|
||||
|
||||
const_preorder_iterator(void) { }
|
||||
const_preorder_iterator(const const_iterator& iter) : const_iterator(iter) { }
|
||||
|
||||
const_preorder_iterator& operator++(void)
|
||||
{
|
||||
pre_inc(this->current, this->iter_depth);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_preorder_iterator& operator--(void)
|
||||
{
|
||||
pre_dec(this->current, this->iter_depth);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Skips the children of this node and moves
|
||||
* to what would normally be the next node
|
||||
* had the children actually been visited. */
|
||||
const_preorder_iterator& prune(void)
|
||||
{
|
||||
while (this->current->next_sibling == NULL)
|
||||
{
|
||||
this->current = this->current->parent;
|
||||
this->iter_depth--;
|
||||
if (this->current == NULL)
|
||||
return *this;
|
||||
}
|
||||
this->current = this->current->next_sibling;
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** Iterates through nodes that have the same parent and does not
|
||||
* allow changes.
|
||||
*/
|
||||
class const_sibling_iterator : public virtual const_iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
explicit const_sibling_iterator(tree_node<N>* current) : const_iterator(current) { }
|
||||
|
||||
public:
|
||||
|
||||
const_sibling_iterator(void) { }
|
||||
const_sibling_iterator(const const_iterator& iter) : const_iterator(iter) { }
|
||||
|
||||
const_sibling_iterator& operator++(void)
|
||||
{
|
||||
sib_inc(this->current);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_sibling_iterator operator ++ (int)
|
||||
{
|
||||
const_sibling_iterator tmp(*this);
|
||||
sib_inc(this->current);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const_sibling_iterator& operator--(void)
|
||||
{
|
||||
sib_dec(this->current);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_sibling_iterator operator -- (int)
|
||||
{
|
||||
const_sibling_iterator tmp(*this);
|
||||
sib_dec(this->current);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const_sibling_iterator operator + (unsigned int n) const
|
||||
{
|
||||
const_sibling_iterator i(*this);
|
||||
|
||||
while (n-- > 0)
|
||||
++i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
const_sibling_iterator operator - (unsigned int n) const
|
||||
{
|
||||
const_sibling_iterator i(*this);
|
||||
|
||||
while (n-- > 0)
|
||||
--i;
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
template<class N>
|
||||
void tree<N>::iterator::clear(void)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
for (sibling_iterator i(beginChildren());
|
||||
i != endChildren(); )
|
||||
{
|
||||
i.clear();
|
||||
++i;
|
||||
(i - 1).destroy();
|
||||
}
|
||||
|
||||
current->first_child = NULL;
|
||||
current->last_child = NULL;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::erase(void)
|
||||
{
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
/* remove all children and grandchildren */
|
||||
clear();
|
||||
|
||||
/* make copies because there is an ordering
|
||||
problem updating the previous and next links */
|
||||
tree_node<N>* old_prev = current->prev_sibling;
|
||||
tree_node<N>* old_next = current->next_sibling;
|
||||
|
||||
if (old_prev != NULL)
|
||||
old_prev->next_sibling = old_next;
|
||||
|
||||
if (old_next != NULL)
|
||||
old_next->prev_sibling = old_prev;
|
||||
|
||||
if (current->parent->first_child == current)
|
||||
current->parent->first_child = old_next;
|
||||
|
||||
if (current->parent->last_child == current)
|
||||
current->parent->last_child = old_prev;
|
||||
|
||||
/* destroy has no parameters, so gcc complains that it
|
||||
can't find the method unless this is made explicit */
|
||||
super::destroy();
|
||||
|
||||
return iterator(old_next);
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::insert(const N& data)
|
||||
{
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
tree_node<N>* p = new tree_node<N>(data);
|
||||
p->parent = current->parent;
|
||||
p->first_child = p->last_child = NULL;
|
||||
|
||||
p->prev_sibling = current->prev_sibling;
|
||||
p->next_sibling = current;
|
||||
|
||||
if (current->prev_sibling != NULL)
|
||||
current->prev_sibling->next_sibling = p;
|
||||
else
|
||||
current->parent->first_child = p;
|
||||
|
||||
current->prev_sibling = p;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::insert(const tree<N>& t)
|
||||
{
|
||||
assert(this->current != NULL);
|
||||
|
||||
return absorb_before(new tree<N>(t));
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::insert_after(const N& data)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
tree_node<N>* p = new tree_node<N>(data);
|
||||
p->parent = current->parent;
|
||||
p->first_child = p->last_child = NULL;
|
||||
|
||||
p->prev_sibling = current;
|
||||
p->next_sibling = current->next_sibling;
|
||||
|
||||
if (current->next_sibling != NULL)
|
||||
current->next_sibling->prev_sibling = p;
|
||||
else
|
||||
current->parent->last_child = p;
|
||||
|
||||
current->next_sibling = p;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::insert_after(const tree<N>& t)
|
||||
{
|
||||
assert(this->current != NULL);
|
||||
|
||||
return absorb_after(new tree<N>(t));
|
||||
}
|
||||
|
||||
template<class N>
|
||||
void tree<N>::iterator::pop_back(void)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
assert(current->last_child != NULL);
|
||||
assert(current->last_child->next_sibling == NULL);
|
||||
|
||||
tree_node<N>* p = current->last_child;
|
||||
current->last_child = p->prev_sibling;
|
||||
|
||||
if (p->prev_sibling != NULL)
|
||||
p->prev_sibling->next_sibling = NULL;
|
||||
else
|
||||
current->first_child = NULL;
|
||||
|
||||
delete p;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
void tree<N>::iterator::pop_front(void)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
assert(current->first_child != NULL);
|
||||
assert(current->first_child->prev_sibling == NULL);
|
||||
|
||||
tree_node<N>* p = current->first_child;
|
||||
current->first_child = p->next_sibling;
|
||||
|
||||
if (p->next_sibling != NULL)
|
||||
p->next_sibling->prev_sibling = NULL;
|
||||
else
|
||||
current->last_child = NULL;
|
||||
|
||||
delete p;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::push_back(const N& data)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
tree_node<N>* p = new tree_node<N>(data);
|
||||
p->parent = current;
|
||||
p->first_child = p->last_child = NULL;
|
||||
|
||||
if (current->last_child == NULL)
|
||||
{
|
||||
current->first_child = current->last_child = p;
|
||||
p->prev_sibling = p->next_sibling = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->prev_sibling = current->last_child;
|
||||
p->next_sibling = NULL;
|
||||
current->last_child->next_sibling = p;
|
||||
current->last_child = p;
|
||||
}
|
||||
|
||||
return iterator(p);
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::push_back(const tree<N>& t)
|
||||
{
|
||||
assert(this->current != NULL);
|
||||
|
||||
return absorb_back(new tree<N>(t));
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::push_front(const N& data)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
tree_node<N>* p = new tree_node<N>(data);
|
||||
p->parent = current;
|
||||
p->first_child = p->last_child = NULL;
|
||||
|
||||
if (current->first_child == NULL)
|
||||
{
|
||||
current->first_child = current->last_child = p;
|
||||
p->prev_sibling = p->next_sibling = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->prev_sibling = NULL;
|
||||
p->next_sibling = current->first_child;
|
||||
current->first_child->prev_sibling = p;
|
||||
current->first_child = p;
|
||||
}
|
||||
|
||||
return iterator(p);
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::push_front(const tree<N>& t)
|
||||
{
|
||||
assert(this->current != NULL);
|
||||
|
||||
return absorb_front(new tree<N>(t));
|
||||
}
|
||||
|
||||
template<class N>
|
||||
N tree<N>::iterator::replace(const N& data)
|
||||
{
|
||||
N ret(this->current->data);
|
||||
this->current->data = data;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
size_t tree<N>::iterator::size(void) const
|
||||
{
|
||||
assert(this->current != NULL);
|
||||
|
||||
size_t s = 1;
|
||||
|
||||
for (typename tree<N>::sibling_iterator i(beginChildren());
|
||||
i != endChildren(); ++i)
|
||||
{
|
||||
s += i.size();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::splice_after(tree<N>& t)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
|
||||
tree_node<N>* p = t.master->next_sibling;
|
||||
t.master->next_sibling = t.master;
|
||||
t.master->prev_sibling = t.master;
|
||||
|
||||
p->parent = current->parent;
|
||||
|
||||
p->prev_sibling = current;
|
||||
p->next_sibling = current->next_sibling;
|
||||
|
||||
if (current->next_sibling != NULL)
|
||||
current->next_sibling->prev_sibling = p;
|
||||
else
|
||||
current->parent->last_child = p;
|
||||
|
||||
current->next_sibling = p;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::splice_back(tree<N>& t)
|
||||
{
|
||||
/* this line necessary for g++ 3.4 onward */
|
||||
tree_node<N>*& current = this->current;
|
||||
|
||||
assert(current != NULL);
|
||||
assert(!t.empty());
|
||||
|
||||
tree_node<N>* p = t.master->next_sibling;
|
||||
t.master->next_sibling = t.master;
|
||||
t.master->prev_sibling = t.master;
|
||||
|
||||
p->parent = current;
|
||||
|
||||
if (current->last_child == NULL)
|
||||
{
|
||||
current->first_child = current->last_child = p;
|
||||
p->prev_sibling = p->next_sibling = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->prev_sibling = current->last_child;
|
||||
p->next_sibling = NULL;
|
||||
current->last_child->next_sibling = p;
|
||||
current->last_child = p;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::splice_before(tree<N>& t)
|
||||
{
|
||||
/* TODO */
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
typename tree<N>::iterator tree<N>::iterator::splice_front(tree<N>& t)
|
||||
{
|
||||
/* TODO */
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** An iterator that can be used to modify the tree. Most of the methods
|
||||
* provided by this class perform actions relative to the current position
|
||||
* of the iterator.
|
||||
*/
|
||||
class iterator : public tree_iterator<N, N&, N*>
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
/* this typedef is very convenient and allows Java-like code */
|
||||
typedef tree_iterator<N, N&, N*> super;
|
||||
|
||||
protected:
|
||||
|
||||
iterator(tree_node<N>* current) : super(current) { }
|
||||
|
||||
public:
|
||||
|
||||
/** Creates an iterator that doesn't point to anything yet. */
|
||||
iterator(void) { }
|
||||
|
||||
/** Copy constructor */
|
||||
iterator(const iterator& iter) : super(iter) { }
|
||||
|
||||
/** Converts an iterator to a const_iterator. This conversion
|
||||
* is one-way; const_iterator does not have a corresponding
|
||||
* conversion function to iterator.
|
||||
*/
|
||||
operator const_iterator() const
|
||||
{ return const_iterator(this->current); }
|
||||
|
||||
typename super::reference
|
||||
operator * (void) const { return this->current->data; }
|
||||
|
||||
typename super::pointer
|
||||
operator -> (void) const { return &(this->current->data); }
|
||||
|
||||
/** Identical to the splice_after method except deletes the tree
|
||||
* after performing the splice.
|
||||
*
|
||||
* @return An iterator pointing to the root of the absorbed tree.
|
||||
*/
|
||||
iterator absorb_after(tree<N>* t)
|
||||
{
|
||||
assert(t != NULL);
|
||||
assert(!t->empty());
|
||||
|
||||
iterator i = splice_after(*t);
|
||||
delete t;
|
||||
return i;
|
||||
}
|
||||
|
||||
/** Identical to the splice_back method except deletes the tree
|
||||
* after performing the splice.
|
||||
*
|
||||
* @return An iterator pointing to the root of the absorbed tree.
|
||||
*/
|
||||
iterator absorb_back(tree<N>* t)
|
||||
{
|
||||
#if !defined(TREE_NO_ERROR_CHECKING) && defined(TREE_EXCEPTIONS)
|
||||
if (t == NULL || t->empty())
|
||||
{
|
||||
throw typename tree<N>::null_tree_exception("in absorb_back");
|
||||
}
|
||||
#else
|
||||
assert(t != NULL);
|
||||
assert(!t->empty());
|
||||
#endif
|
||||
|
||||
iterator i = splice_back(*t);
|
||||
delete t;
|
||||
return i;
|
||||
}
|
||||
|
||||
/** Identical to the splice_before method except deletes the tree
|
||||
* after performing the splice.
|
||||
*
|
||||
* @return An iterator pointing to the root of the absorbed tree.
|
||||
*/
|
||||
iterator absorb_before(tree<N>* t)
|
||||
{
|
||||
assert(t != NULL);
|
||||
assert(!t->empty());
|
||||
|
||||
iterator i = splice_before(*t);
|
||||
delete t;
|
||||
return i;
|
||||
}
|
||||
|
||||
/** Identical to the splice_front method except deletes the tree
|
||||
* after performing the splice.
|
||||
*
|
||||
* @return An iterator pointing to the root of the absorbed tree.
|
||||
*/
|
||||
iterator absorb_front(tree<N>* t)
|
||||
{
|
||||
assert(t != NULL);
|
||||
assert(!t->empty());
|
||||
|
||||
iterator i = splice_front(*t);
|
||||
delete t;
|
||||
return i;
|
||||
}
|
||||
|
||||
sibling_iterator beginChildren(void) const
|
||||
{ return sibling_iterator(iterator(this->current->first_child)); }
|
||||
|
||||
/** Removes all children and grandchildren of this node
|
||||
*/
|
||||
void clear(void);
|
||||
|
||||
sibling_iterator endChildren(void) const
|
||||
{ return sibling_iterator(iterator(NULL)); }
|
||||
|
||||
/** Removes this node and returns an iterator pointing
|
||||
* to the next node. */
|
||||
iterator erase(void);
|
||||
|
||||
/** Inserts a new node before this node and returns an
|
||||
* iterator pointing to the new node. */
|
||||
iterator insert(const N& data);
|
||||
|
||||
iterator insert(const tree<N>& t);
|
||||
|
||||
/** Inserts a new node after this node and returns an
|
||||
* iterator pointing to the new node. */
|
||||
iterator insert_after(const N& data);
|
||||
|
||||
iterator insert_after(const tree<N>& t);
|
||||
|
||||
iterator parent(void) const
|
||||
{ return this->current->parent; }
|
||||
|
||||
/** Removes the last child of this node.
|
||||
*/
|
||||
void pop_back(void);
|
||||
|
||||
/** Removes the first child of this node.
|
||||
*/
|
||||
void pop_front(void);
|
||||
|
||||
/** Adds a node to the end of this position's child list.
|
||||
*
|
||||
* @param data Data for the new node.
|
||||
*
|
||||
* @return An iterator pointing to the new node.
|
||||
*/
|
||||
iterator push_back (const N& data);
|
||||
|
||||
/** Adds a copy of a tree to the end of this position's child list.
|
||||
*
|
||||
* @param t The tree to copy.
|
||||
*
|
||||
* @return An iterator pointing to the root of the inserted subtree.
|
||||
*/
|
||||
iterator push_back (const tree<N>& t);
|
||||
|
||||
/** Adds a node to the beginning of this position's child list.
|
||||
*
|
||||
* @param data Data for the new node.
|
||||
*
|
||||
* @return An iterator pointing to the new node.
|
||||
*/
|
||||
iterator push_front(const N& data);
|
||||
|
||||
/** Adds a copy of a tree to the beginning of this position's child list.
|
||||
*
|
||||
* @param t The tree to copy.
|
||||
*
|
||||
* @return An iterator pointing to the root of the inserted subtree.
|
||||
*/
|
||||
iterator push_front(const tree<N>& t);
|
||||
|
||||
/** Replaces the data at this position.
|
||||
*
|
||||
* @param data The new data.
|
||||
*
|
||||
* @return The old data.
|
||||
*/
|
||||
N replace(const N& data);
|
||||
|
||||
/** Determines the size of the subtree below and including this position.
|
||||
*
|
||||
* @return The size of this subtree.
|
||||
*/
|
||||
size_t size(void) const;
|
||||
|
||||
/** Moves nodes from a tree (without copying) such that
|
||||
* the tree becomes the next sibling of this node.
|
||||
*
|
||||
* @param t The tree to move. It will be empty after this method returns.
|
||||
*
|
||||
* @return An iterator pointing to the root of the spliced tree.
|
||||
*/
|
||||
iterator splice_after(tree<N>& t);
|
||||
|
||||
/** Moves nodes from a tree (without copying) such that the tree becomes the last child of this node.
|
||||
*
|
||||
* @param t The tree to move. It will be empty after this method returns.
|
||||
*
|
||||
* @return An iterator pointing to the root of the spliced tree.
|
||||
*/
|
||||
iterator splice_back(tree<N>& t);
|
||||
|
||||
/** Moves nodes from a tree (without copying) such that the tree becomes the previous child of this node.
|
||||
*
|
||||
* @param t The tree to move. It will be empty after this method returns.
|
||||
*
|
||||
* @return An iterator pointing to the root of the spliced tree.
|
||||
*/
|
||||
iterator splice_before(tree<N>& t);
|
||||
|
||||
/** Moves nodes from a tree (without copying) such that the tree becomes the first child of this node.
|
||||
*
|
||||
* @param t The tree to move. It will be empty after this method returns.
|
||||
*
|
||||
* @return An iterator pointing to the root of the spliced tree.
|
||||
*/
|
||||
iterator splice_front(tree<N>& t);
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** Iterates through the graph visiting parents after children and allows changes.
|
||||
*/
|
||||
class postorder_iterator : public virtual iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
explicit postorder_iterator(tree_node<N>* current) : iterator(current) { }
|
||||
|
||||
public:
|
||||
|
||||
postorder_iterator(void) { }
|
||||
postorder_iterator(const iterator& iter) : iterator(iter) { }
|
||||
|
||||
postorder_iterator& operator++(void)
|
||||
{
|
||||
post_inc(this->current, this->iter_depth);
|
||||
return *this;
|
||||
}
|
||||
|
||||
postorder_iterator& operator--(void)
|
||||
{
|
||||
post_dec(this->current, this->iter_depth);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** Iterates through the graph visiting parents before children and allows changes.
|
||||
*/
|
||||
class preorder_iterator : public virtual iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
explicit preorder_iterator(tree_node<N>* current) : iterator(current) { }
|
||||
|
||||
public:
|
||||
|
||||
preorder_iterator(void) { }
|
||||
preorder_iterator(const iterator& iter) : iterator(iter) { }
|
||||
|
||||
preorder_iterator& operator++(void)
|
||||
{
|
||||
pre_inc(this->current, this->iter_depth);
|
||||
return *this;
|
||||
}
|
||||
|
||||
preorder_iterator& operator--(void)
|
||||
{
|
||||
pre_dec(this->current, this->iter_depth);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** Iterates through nodes that have the same parent and allows changes.
|
||||
*/
|
||||
class sibling_iterator : public virtual iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
private:
|
||||
|
||||
explicit sibling_iterator(tree_node<N>* current) : iterator(current) { }
|
||||
|
||||
public:
|
||||
|
||||
sibling_iterator(void) { }
|
||||
|
||||
sibling_iterator(const iterator& iter) : iterator(iter) { }
|
||||
|
||||
sibling_iterator& operator ++ (void)
|
||||
{
|
||||
sib_inc(this->current);
|
||||
return *this;
|
||||
}
|
||||
|
||||
sibling_iterator operator ++ (int)
|
||||
{
|
||||
sibling_iterator tmp(*this);
|
||||
sib_inc(this->current);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
sibling_iterator& operator -- (void)
|
||||
{
|
||||
sib_dec(this->current);
|
||||
return *this;
|
||||
}
|
||||
|
||||
sibling_iterator operator -- (int)
|
||||
{
|
||||
sibling_iterator tmp(*this);
|
||||
sib_dec(this->current);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
sibling_iterator operator + (unsigned int n) const
|
||||
{
|
||||
sibling_iterator i(*this);
|
||||
|
||||
while (n-- > 0)
|
||||
++i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
sibling_iterator& operator += (unsigned int n)
|
||||
{
|
||||
while (n-- > 0)
|
||||
sib_inc(this->current);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
sibling_iterator operator - (unsigned int n) const
|
||||
{
|
||||
sibling_iterator i(*this);
|
||||
|
||||
while (n-- > 0)
|
||||
--i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
sibling_iterator& operator -= (unsigned int n)
|
||||
{
|
||||
while (n-- > 0)
|
||||
sib_dec(this->current);
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
template <class N>
|
||||
template <class InputIterator>
|
||||
tree<N>::tree(InputIterator first, InputIterator last, unsigned int n)
|
||||
{
|
||||
assert(n != 0);
|
||||
|
||||
createMaster();
|
||||
|
||||
if (first == last)
|
||||
return;
|
||||
|
||||
setRoot(*first);
|
||||
|
||||
/* don't directly initialize i to first + 1 because not all STL
|
||||
iterators support addition */
|
||||
InputIterator i(first);
|
||||
|
||||
if (++i == last)
|
||||
return;
|
||||
|
||||
/* Make a list of leaves. Initially the list contains only the
|
||||
root. Pick a leaf and add items to it until it is full.
|
||||
Added items become new leaves. Continue until there
|
||||
are no more items */
|
||||
|
||||
std::list<typename tree<N>::iterator> leaves;
|
||||
leaves.push_back(getRoot());
|
||||
|
||||
for (;;)
|
||||
{
|
||||
typename tree<N>::iterator leaf(leaves.front());
|
||||
|
||||
for (unsigned int k = 0; k < n; ++k)
|
||||
{
|
||||
leaves.push_back(leaf.push_back(*i));
|
||||
|
||||
if (++i == last)
|
||||
return;
|
||||
}
|
||||
|
||||
leaves.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
template <class N>
|
||||
void tree<N>::copy_subtree(tree<N>::const_iterator subtree)
|
||||
{
|
||||
/* Copying replaces this tree. */
|
||||
clear();
|
||||
|
||||
/* Original is empty, so leave it empty. */
|
||||
if (subtree == NULL)
|
||||
return;
|
||||
|
||||
/* Copy the root data. */
|
||||
sibling_iterator root(setRoot(*subtree));
|
||||
|
||||
/* Recursively copy the children. */
|
||||
for (const_sibling_iterator i(subtree.beginChildren());
|
||||
i != subtree.endChildren(); ++i)
|
||||
root.absorb_back(new tree<N>(i));
|
||||
}
|
||||
|
||||
template <class N>
|
||||
void tree<N>::clear(void)
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
/* delete all nodes bottom-up */
|
||||
for (postorder_iterator i(beginPost()); i != endPost(); )
|
||||
{
|
||||
postorder_iterator tmp(i);
|
||||
++i;
|
||||
tmp.destroy();
|
||||
}
|
||||
|
||||
/* Preserve master invariant. */
|
||||
master->first_child = master->last_child = NULL;
|
||||
master->prev_sibling = master->next_sibling = master;
|
||||
|
||||
/* Leave the master for the destructor. */
|
||||
}
|
||||
|
||||
template <class N>
|
||||
size_t tree<N>::height(void) const
|
||||
{
|
||||
size_t h = 0;
|
||||
|
||||
for (const_preorder_iterator i(beginPre()); i != endPre(); ++i)
|
||||
{
|
||||
if (static_cast<size_t>(i.depth() + 1) > h)
|
||||
h = i.depth() + 1;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
template <class N>
|
||||
size_t tree<N>::height_leftmost(void) const
|
||||
{
|
||||
size_t h = 0;
|
||||
|
||||
tree_node<N>* p = master->next_sibling;
|
||||
|
||||
if (p != master)
|
||||
{
|
||||
do {
|
||||
++h;
|
||||
p = p->first_child;
|
||||
} while (p != NULL);
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
size_t tree<N>::size(void) const
|
||||
{
|
||||
size_t s = 0;
|
||||
|
||||
for (const_preorder_iterator i(beginPre()); i != endPre(); ++i)
|
||||
++s;
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,871 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TREE_H
|
||||
#define TREE_H
|
||||
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
/* master invariant checks are sprinkled throughout to check
|
||||
for catastrophic errors */
|
||||
#if defined(TREE_NO_ERROR_CHECKING)
|
||||
#define TREE_MASTER_INVARIANT
|
||||
#else
|
||||
#if defined(TREE_EXCEPTIONS)
|
||||
#define TREE_MASTER_INVARIANT check_master_invariant()
|
||||
#else
|
||||
#define TREE_MASTER_INVARIANT assert(master != NULL); \
|
||||
assert(master->next_sibling != NULL)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* experimental */
|
||||
// #define TREE_POINTER_SPECIALIZATION
|
||||
|
||||
namespace taj /* my initials */
|
||||
{
|
||||
|
||||
/** Provides a generic n-ary acyclic tree container that behaves similarly
|
||||
* to and is mostly compatible with other standard C++ templates. Various
|
||||
* iterators are provided, with pruning options. Iterators are also used
|
||||
* to represent subtrees.
|
||||
*
|
||||
* In the spirit of the standard template library, the BSD license makes
|
||||
* my tree class available for all to use. I would appreciate receiving
|
||||
* patches to fix any bugs you may discover or suggestions on how to
|
||||
* improve the template.
|
||||
*
|
||||
* The STL list template was my initial inspiration for how to implement
|
||||
* the tree class, but I determined there was little benefit from
|
||||
* starting with that code. This template class does not use any code
|
||||
* from the STL classes, but is designed to be compatible and have similar
|
||||
* method names for consistency. I intend for this class to be very
|
||||
* efficient in terms of size and speed, just like the STL classes.
|
||||
*
|
||||
* The std::list template uses many supporting classes that are found in
|
||||
* the std namespace or public in the std::list namespace. This tree
|
||||
* template does not pollute the global namespace as much by keeping all
|
||||
* the supporting classes inside the main class. If the user includes
|
||||
* the taj namespace, the only name that gets sucked into the enclosing
|
||||
* namespace is tree. I feel this is a better design. The following were
|
||||
* some motivating factors:
|
||||
*
|
||||
* 1) The tree_node class should be invisible to the user. The user wants to
|
||||
* think of the N in tree<N> as the node type of the tree. In the standard
|
||||
* list template, struct _List_node is similarly irrelevant to the user
|
||||
* but unnecessarily appears in the std namespace.
|
||||
*
|
||||
* 2) The base template for the iterators should be a true class instead of a
|
||||
* wide-open struct. Furthermore, it should not be accessible to the user.
|
||||
* A consequence of nesting the iterators inside the tree class is needing
|
||||
* to make the tree their friend, but this is an example of how to use
|
||||
* friends correctly.
|
||||
*
|
||||
* There is a lot of code here, so I have divided it into several header
|
||||
* files and code files. The only header the user needs to include is tree.h.
|
||||
*
|
||||
* tree.h - the main header file for the tree class
|
||||
* tree_node.h - class that represents tree nodes
|
||||
* tree_iterator.h - base class for ALL iterators
|
||||
* iterator.h - base class for ONLY non-const iterators
|
||||
* const_iterator.h - base class for ONLY const_iterators
|
||||
* (const_)preorder_iterator.h - iterators for preorder traversal
|
||||
* (const_)postorder_iterator.h - iterators for postorder traversal
|
||||
* (const_)bfs_iterator.h - iterators for breadth-first traversal
|
||||
* (const_)sibling_iterator.h - iterators for a single tree level
|
||||
*
|
||||
* There is no "in-order" traversal because the tree is not necessarily
|
||||
* binary. There are also .cc files which get included by this file, because
|
||||
* all the code for the template needs to be in tree.h.
|
||||
*
|
||||
* Note concerning GCC 3.4: Template code checks are much stricter in 3.4.
|
||||
* It is possible to have a template that compiles with GCC 3.3 but that does
|
||||
* not compile with 3.4. The following GCC "bug" reports explain the
|
||||
* workarounds, which have been incorporated into this template class.
|
||||
*
|
||||
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15552
|
||||
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17649
|
||||
*
|
||||
* The same issue has found its way into the C++ FAQ
|
||||
*
|
||||
* http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12
|
||||
* http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13
|
||||
*
|
||||
* A final note: C++ template code is weird and classes as complicated as
|
||||
* this one will give your compiler good exercise. I have tested this
|
||||
* class with the Debian releases of GCC 3.3.5, GCC 3.4.4, GCC 4.0.3 and
|
||||
* I expect to use it with later versions. I have no idea if it works
|
||||
* under other C++ compilers. If there are changes that will allow it to
|
||||
* work under more compilers while still allowing it to work under GCC,
|
||||
* then you are encouraged to suggest them.
|
||||
*
|
||||
* @author Troy A. Johnson
|
||||
*/
|
||||
template <class N>
|
||||
class tree
|
||||
{
|
||||
private:
|
||||
|
||||
#include "tree_node.h"
|
||||
#include "tree_iterator.h"
|
||||
|
||||
/** The real root of the tree as opposed to the first node inserted by
|
||||
* the user. Also used as the end for preorder and postorder iterators
|
||||
* since they finish by "falling off" the root of the tree. (The
|
||||
* breadth-first iterator uses NULL for its end because it falls off
|
||||
* the leaves.) As far as the user is concerned, the first node is
|
||||
* master->next_sibling. This corresponds to the _M_node in
|
||||
* _List_alloc_base for the standard list template.
|
||||
*/
|
||||
tree_node<N>* master;
|
||||
|
||||
public:
|
||||
|
||||
/* avoid annoying forward reference problems */
|
||||
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
|
||||
class sibling_iterator;
|
||||
class const_sibling_iterator;
|
||||
|
||||
class preorder_iterator;
|
||||
class const_preorder_iterator;
|
||||
|
||||
class postorder_iterator;
|
||||
class const_postorder_iterator;
|
||||
|
||||
class bfs_iterator;
|
||||
class const_bfs_iterator;
|
||||
|
||||
#include "iterator.h"
|
||||
#include "const_iterator.h"
|
||||
|
||||
#include "sibling_iterator.h"
|
||||
#include "const_sibling_iterator.h"
|
||||
|
||||
#include "preorder_iterator.h"
|
||||
#include "const_preorder_iterator.h"
|
||||
|
||||
#include "postorder_iterator.h"
|
||||
#include "const_postorder_iterator.h"
|
||||
|
||||
#include "bfs_iterator.h"
|
||||
#include "const_bfs_iterator.h"
|
||||
|
||||
/* no dfs_iterator - use preorder_iterator instead */
|
||||
|
||||
/** Thrown if tree exceptions are turned on and a NULL is encountered
|
||||
* in an incorrect place. */
|
||||
class null_tree_exception : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
null_tree_exception(const std::string& s)
|
||||
: std::runtime_error("null_tree_exception " + s) { }
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
#if !defined(TREE_NO_ERROR_CHECKING) && defined(TREE_EXCEPTIONS)
|
||||
void check_master_invariant(void)
|
||||
{
|
||||
if (master == NULL)
|
||||
throw new null_tree_exception("tree master is null");
|
||||
|
||||
if (master->next_sibling == NULL)
|
||||
throw new null_tree_exception("tree master->next_sibling is null");
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Initializes the master node. Every tree constructor needs to
|
||||
* do this so it's a separate method.
|
||||
*/
|
||||
void createMaster(void)
|
||||
{
|
||||
master = new tree_node<N>;
|
||||
master->parent = NULL;
|
||||
master->first_child = master->last_child = NULL;
|
||||
master->prev_sibling = master->next_sibling = master;
|
||||
}
|
||||
|
||||
/** Replaces this tree with copies of all nodes below (and including)
|
||||
* the node pointed to by subtree. Used by multiple constructors.
|
||||
*
|
||||
* @param subtree Location from which to begin copying.
|
||||
*/
|
||||
void copy_subtree(const_iterator subtree);
|
||||
|
||||
/** Determines the leftmost child of this tree.
|
||||
* Used as a starting point for postorder traversals.
|
||||
*
|
||||
* @return A pointer to the leftmost node or master if
|
||||
* the tree is empty.
|
||||
*/
|
||||
tree_node<N>* leftmostChild(void) const
|
||||
{
|
||||
TREE_MASTER_INVARIANT;
|
||||
|
||||
tree_node<N>* p = master->next_sibling;
|
||||
|
||||
while (p->first_child != NULL)
|
||||
p = p->first_child;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/** Provides access to an iterator suitable for postorder traversal,
|
||||
* initially pointing to the leftmost child of this tree.
|
||||
*
|
||||
* @return An iterator for postorder traversal.
|
||||
*/
|
||||
postorder_iterator beginPost(void)
|
||||
{ return postorder_iterator(leftmostChild()); }
|
||||
|
||||
/** Provides access to an iterator suitable for postorder traversal,
|
||||
* initially pointing to the leftmost child of this tree.
|
||||
*
|
||||
* @return A constant iterator for postorder traversal.
|
||||
*/
|
||||
const_postorder_iterator beginPost(void) const
|
||||
{ return const_postorder_iterator(leftmostChild()); }
|
||||
|
||||
/** Provides access to an iterator representing the end of a
|
||||
* postorder traversal.
|
||||
*
|
||||
* @return The end of a postorder traversal.
|
||||
*/
|
||||
postorder_iterator endPost(void)
|
||||
{ return postorder_iterator(master); }
|
||||
|
||||
/** Provides access to an iterator representing the end of a
|
||||
* constant postorder traversal.
|
||||
*
|
||||
* @return The end of a constant postorder traversal.
|
||||
*/
|
||||
const_postorder_iterator endPost(void) const
|
||||
{ return const_postorder_iterator(master); }
|
||||
|
||||
/** Provides access to an iterator suitable for preorder traversal,
|
||||
* initially pointing to the root of this tree.
|
||||
*
|
||||
* @return An iterator for preorder traversal.
|
||||
*/
|
||||
preorder_iterator beginPre(void)
|
||||
{ return preorder_iterator(master->next_sibling); }
|
||||
|
||||
/** Provides access to an iterator suitable for preorder traversal,
|
||||
* initially pointing to the root of this tree.
|
||||
*
|
||||
* @return A constant iterator for preorder traversal.
|
||||
*/
|
||||
const_preorder_iterator beginPre(void) const
|
||||
{ return const_preorder_iterator(master->next_sibling); }
|
||||
|
||||
/** Provides access to an iterator representing the end of a
|
||||
* preorder traversal.
|
||||
*
|
||||
* @return The end of a preorder traversal.
|
||||
*/
|
||||
preorder_iterator endPre(void)
|
||||
{ return preorder_iterator(master); }
|
||||
|
||||
/** Provides access to an iterator representing the end of a
|
||||
* constant preorder traversal.
|
||||
*
|
||||
* @return The end of a constant preorder traversal.
|
||||
*/
|
||||
const_preorder_iterator endPre(void) const
|
||||
{ return const_preorder_iterator(master); }
|
||||
|
||||
/** Provides access to an iterator suitable for breadth-first traversal,
|
||||
* initially pointing to the root of this tree.
|
||||
*
|
||||
* @return An iterator for breadth-first traversal.
|
||||
*/
|
||||
bfs_iterator beginBfs(void)
|
||||
{ return bfs_iterator(master->next_sibling); }
|
||||
|
||||
/** Provides access to an iterator suitable for breadth-first traversal,
|
||||
* initially pointing to the root of this tree.
|
||||
*
|
||||
* @return A constant iterator for breadth-first traversal.
|
||||
*/
|
||||
const_bfs_iterator beginBfs(void) const
|
||||
{ return const_bfs_iterator(master->next_sibling); }
|
||||
|
||||
/** Provides access to an iterator representing the end of a
|
||||
* breadth-first traversal.
|
||||
*
|
||||
* @return The end of a breadth-first traversal.
|
||||
*/
|
||||
bfs_iterator endBfs(void)
|
||||
{ return bfs_iterator(NULL); }
|
||||
|
||||
/** Provides access to an iterator representing the end of a
|
||||
* constant breadth-first traversal.
|
||||
*
|
||||
* @return The end of a constant breadth-first traversal.
|
||||
*/
|
||||
const_bfs_iterator endBfs(void) const
|
||||
{ return const_bfs_iterator(NULL); }
|
||||
|
||||
/** Creates an empty tree. A root node can be created with setRoot later.
|
||||
*/
|
||||
tree(void)
|
||||
{
|
||||
createMaster();
|
||||
}
|
||||
|
||||
/** Creates a single-node tree.
|
||||
*
|
||||
* @param root_data The data to use for the root of the tree.
|
||||
*/
|
||||
explicit tree(const N& root_data)
|
||||
{
|
||||
createMaster();
|
||||
setRoot(root_data);
|
||||
}
|
||||
|
||||
/** Copies an existing subtree.
|
||||
*
|
||||
* @param subtree The root of the original subtree
|
||||
* from which to make the copy.
|
||||
*/
|
||||
explicit tree(const_iterator subtree)
|
||||
{
|
||||
createMaster();
|
||||
copy_subtree(subtree);
|
||||
}
|
||||
|
||||
/** Copies an existing tree.
|
||||
*
|
||||
* @param orig The original tree from which to make the copy.
|
||||
*/
|
||||
tree(const tree<N>& orig)
|
||||
{
|
||||
createMaster();
|
||||
copy_subtree(orig.getRoot());
|
||||
}
|
||||
|
||||
/** Creates a tree using copies of items of another container.
|
||||
* The range copied is [first, last).
|
||||
*
|
||||
* @param first First item to put in the tree.
|
||||
* @param last The item after the final item to put in the tree.
|
||||
* @param n Creates a n-ary tree. Must be greater than zero.
|
||||
*/
|
||||
template <class InputIterator>
|
||||
tree(InputIterator first, InputIterator last, unsigned int n);
|
||||
|
||||
/** Copies an existing tree.
|
||||
*
|
||||
* @param orig The original tree from which to make the copy.
|
||||
*
|
||||
* @return A reference to this tree to be used in chained assignments.
|
||||
*/
|
||||
const tree<N>& operator = (const tree<N>& orig)
|
||||
{
|
||||
copy_subtree(orig.getRoot());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Empties and destroys the tree.
|
||||
*/
|
||||
virtual ~tree(void)
|
||||
{
|
||||
TREE_MASTER_INVARIANT;
|
||||
clear();
|
||||
delete master;
|
||||
}
|
||||
|
||||
/** Empties the tree. All nodes are deleted. If the node type
|
||||
* is a pointer, it is the user's responsibility to delete
|
||||
* the data to which they point before clearing the tree.
|
||||
*/
|
||||
void clear(void);
|
||||
|
||||
/** Checks if the tree is empty.
|
||||
*
|
||||
* @return true if the tree is empty, false otherwise.
|
||||
*/
|
||||
bool empty(void) const
|
||||
{
|
||||
TREE_MASTER_INVARIANT;
|
||||
return (master->next_sibling == master);
|
||||
}
|
||||
|
||||
/** Provides access to the root of the tree.
|
||||
*
|
||||
* @return An iterator pointing at the root node.
|
||||
*/
|
||||
iterator getRoot(void)
|
||||
{
|
||||
TREE_MASTER_INVARIANT;
|
||||
return iterator(master->next_sibling);
|
||||
}
|
||||
|
||||
/** Provides access to the root of an unmodifiable tree.
|
||||
*
|
||||
* @return An iterator pointing at the root node.
|
||||
*/
|
||||
const_iterator getRoot(void) const
|
||||
{
|
||||
TREE_MASTER_INVARIANT;
|
||||
return const_iterator(master->next_sibling);
|
||||
}
|
||||
|
||||
/** Determines the height of the tree. This operation is
|
||||
* general and is linear in the size of the tree, not
|
||||
* the height.
|
||||
*
|
||||
* @return The height of the tree.
|
||||
*/
|
||||
size_t height(void) const;
|
||||
|
||||
/** Determines the height of the tree using
|
||||
* the leftmost grandchild of the root. This operation is
|
||||
* guaranteed to be linear in the height of the tree, but
|
||||
* may not be the true height for some trees.
|
||||
*
|
||||
* @return The height of the leftmost grandchild of the root.
|
||||
*/
|
||||
size_t height_leftmost(void) const;
|
||||
|
||||
/** Sets the data of the root node, or creates one if it was not set
|
||||
* when the tree was created.
|
||||
*
|
||||
* @return An iterator pointing to the root node.
|
||||
*/
|
||||
iterator setRoot(const N& root_data)
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
tree_node<N>* root = new tree_node<N>(root_data);
|
||||
root->parent = NULL;
|
||||
root->first_child = root->last_child = NULL;
|
||||
root->next_sibling = root->prev_sibling = master;
|
||||
|
||||
master->prev_sibling = master->next_sibling = root;
|
||||
}
|
||||
else
|
||||
*getRoot() = root_data;
|
||||
|
||||
return getRoot();
|
||||
}
|
||||
|
||||
/** Determines the number of nodes in the tree.
|
||||
* Unfortunately this requires a full tree traversal.
|
||||
* This could be expensive, but it's far simpler than
|
||||
* making iterators aware of what tree they are modifying
|
||||
* and updating the current size of that tree. For simple
|
||||
* insertion and deletion that might not be difficult,
|
||||
* but for more complex operations it very well might be.
|
||||
* Doing it this way makes size a known expensive operation
|
||||
* instead of adding overhead to a large number of other calls.
|
||||
* If the user knows how many nodes they have added or deleted
|
||||
* since their last size call, then they can compute the current
|
||||
* size without calling size. It should be noted that the
|
||||
* standard library list template works the same way.
|
||||
*
|
||||
* @return The number of nodes in the tree.
|
||||
*/
|
||||
size_t size(void) const;
|
||||
};
|
||||
|
||||
#include "tree_iterator.cc"
|
||||
|
||||
#include "iterator.cc"
|
||||
|
||||
#include "const_iterator.cc"
|
||||
|
||||
/* keep this include last */
|
||||
#include "tree.cc"
|
||||
|
||||
/* TODO - Pointer specialization
|
||||
|
||||
This is experimental and may not work at all.
|
||||
*/
|
||||
|
||||
#if defined(TREE_POINTER_SPECIALIZATION)
|
||||
template class tree<void*>;
|
||||
|
||||
template <class N>
|
||||
class tree<N*> : private tree<void*>
|
||||
{
|
||||
public:
|
||||
|
||||
/* do not prefix these forward declarations with tree<N*>:: */
|
||||
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
|
||||
class sibling_iterator;
|
||||
class const_sibling_iterator;
|
||||
|
||||
class preorder_iterator;
|
||||
class const_preorder_iterator;
|
||||
|
||||
class postorder_iterator;
|
||||
class const_postorder_iterator;
|
||||
|
||||
class bfs_iterator;
|
||||
class const_bfs_iterator;
|
||||
|
||||
class iterator : private virtual tree<void*>::iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
typedef class tree<N*>::iterator self;
|
||||
typedef class tree<void*>::iterator super;
|
||||
|
||||
protected:
|
||||
|
||||
iterator(const super& iter) : super(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
iterator(void) { }
|
||||
|
||||
iterator(const self& iter) : super(iter) { }
|
||||
|
||||
// operator const_iterator()
|
||||
// { return static_cast<typename tree<void*>::const_iterator>(*this); }
|
||||
|
||||
bool operator == (const self& iter) const
|
||||
{ return super(*this) == super(iter); }
|
||||
|
||||
bool operator != (const self& iter) const
|
||||
{ return super(*this) != super(iter); }
|
||||
|
||||
using super::clear;
|
||||
|
||||
using super::depth;
|
||||
|
||||
typename tree<N*>::sibling_iterator beginChildren(void) const
|
||||
{ return self(super::beginChildren()); }
|
||||
|
||||
typename tree<N*>::sibling_iterator endChildren(void) const
|
||||
{ return self(super::endChildren()); }
|
||||
|
||||
N*&
|
||||
operator * (void) const { return reinterpret_cast<N*&>(this->current->data); }
|
||||
|
||||
N**
|
||||
operator -> (void) const { return reinterpret_cast<N**>(&(this->current->data)); }
|
||||
|
||||
self absorb_back(tree<N*>* t)
|
||||
{ return super::absorb_back(t); }
|
||||
|
||||
self push_back(N* data)
|
||||
{ return super::push_back(data); }
|
||||
|
||||
N* replace(N* data)
|
||||
{ return reinterpret_cast<N*>(super::replace(data)); }
|
||||
};
|
||||
|
||||
class const_iterator : private virtual tree<void*>::const_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
typedef class tree<N*>::const_iterator self;
|
||||
typedef class tree<void*>::const_iterator super;
|
||||
|
||||
protected:
|
||||
|
||||
const_iterator(const super& iter) : super(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
const_iterator(void) { }
|
||||
|
||||
const_iterator(const self& iter) : super(iter) { }
|
||||
|
||||
bool operator == (const self& iter) const
|
||||
{ return super(*this) == super(iter); }
|
||||
|
||||
bool operator != (const self& iter) const
|
||||
{ return super(*this) != super(iter); }
|
||||
|
||||
using super::depth;
|
||||
|
||||
N* const &
|
||||
operator * (void) const { return reinterpret_cast<N* const &>(this->current->data); }
|
||||
|
||||
N* const *
|
||||
operator -> (void) const { return reinterpret_cast<N* const *>(&(this->current->data)); }
|
||||
};
|
||||
|
||||
class sibling_iterator : public tree<N*>::iterator, private tree<void*>::sibling_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
private:
|
||||
|
||||
sibling_iterator(const tree<void*>::sibling_iterator& iter) : tree<N*>::iterator(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
sibling_iterator(void) { }
|
||||
|
||||
sibling_iterator(const tree<N*>::iterator& iter) : tree<N*>::iterator(iter) { }
|
||||
|
||||
using tree<N*>::iterator::operator *;
|
||||
|
||||
typename tree<N*>::sibling_iterator& operator ++ (void)
|
||||
{ ++static_cast<tree<void*>::sibling_iterator>(*this); return *this; }
|
||||
};
|
||||
#if 0
|
||||
class const_sibling_iterator : public const_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
private:
|
||||
|
||||
// const_sibling_iterator(const tree<void*>::const_sibling_iterator& iter) : const_iterator(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
const_sibling_iterator(const const_iterator& iter) : const_iterator(iter) { }
|
||||
};
|
||||
#endif
|
||||
class preorder_iterator : public tree<N*>::iterator, private tree<void*>::preorder_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
private:
|
||||
|
||||
preorder_iterator(const tree<void*>::preorder_iterator& iter) : tree<N*>::iterator(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
preorder_iterator(const tree<N*>::iterator& iter) : tree<N*>::iterator(iter) { }
|
||||
|
||||
using tree<N*>::iterator::operator ==;
|
||||
using tree<N*>::iterator::operator !=;
|
||||
using tree<N*>::iterator::operator *;
|
||||
|
||||
typename tree<N*>::preorder_iterator& operator ++ (void)
|
||||
{ ++static_cast<tree<void*>::preorder_iterator>(*this); return *this; }
|
||||
|
||||
using tree<N*>::iterator::replace;
|
||||
};
|
||||
|
||||
class const_preorder_iterator : public tree<N*>::const_iterator, private tree<void*>::const_preorder_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
private:
|
||||
|
||||
const_preorder_iterator(const tree<void*>::const_preorder_iterator& iter) : tree<void*>::const_preorder_iterator(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
const_preorder_iterator(const tree<N*>::const_iterator& iter) : tree<N*>::const_iterator(iter) { }
|
||||
|
||||
using tree<N*>::const_iterator::operator *;
|
||||
|
||||
typename tree<N*>::const_preorder_iterator& operator ++ (void)
|
||||
{ ++static_cast<tree<void*>::const_preorder_iterator>(*this); return *this; }
|
||||
};
|
||||
#if 0
|
||||
class postorder_iterator : private tree<void*>::postorder_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
private:
|
||||
|
||||
// postorder_iterator(const tree<void*>::postorder_iterator& iter) : iterator(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
postorder_iterator(const iterator& iter) : tree<void*>::postorder_iterator(iter) { }
|
||||
};
|
||||
|
||||
class const_postorder_iterator : private tree<void*>::const_postorder_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
private:
|
||||
|
||||
// const_postorder_iterator(const tree<void*>::const_postorder_iterator& iter) : const_iterator(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
const_postorder_iterator(const const_iterator& iter) : tree<void*>::const_postorder_iterator(iter) { }
|
||||
};
|
||||
|
||||
class bfs_iterator : private tree<void*>::bfs_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
private:
|
||||
|
||||
// bfs_iterator(const tree<void*>::bfs_iterator& iter) : iterator(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
bfs_iterator(const iterator& iter) : tree<void*>::bfs_iterator(iter) { }
|
||||
};
|
||||
|
||||
class const_bfs_iterator : private tree<void*>::const_bfs_iterator
|
||||
{
|
||||
friend class tree<N*>;
|
||||
|
||||
private:
|
||||
|
||||
// const_bfs_iterator(const tree<void*>::const_bfs_iterator& iter) : const_iterator(iter) { }
|
||||
|
||||
public:
|
||||
|
||||
const_bfs_iterator(const const_iterator& iter) : tree<void*>::const_bfs_iterator(iter) { }
|
||||
};
|
||||
#endif
|
||||
tree(void) : tree<void*>::tree()
|
||||
{
|
||||
}
|
||||
|
||||
/** Creates a single-node tree.
|
||||
*
|
||||
* @param root_data The data to use for the root of the tree.
|
||||
*/
|
||||
explicit tree(N* root_data) : tree<void*>::tree(root_data)
|
||||
{
|
||||
}
|
||||
|
||||
explicit tree(const_iterator subtree) : tree<void*>::tree(subtree)
|
||||
{
|
||||
}
|
||||
|
||||
tree(const tree<N*>& orig) : tree<void*>::tree(orig)
|
||||
{
|
||||
}
|
||||
|
||||
preorder_iterator beginPre(void)
|
||||
{ return tree<void*>::beginPre(); }
|
||||
|
||||
const_preorder_iterator beginPre(void) const
|
||||
{ return tree<void*>::beginPre(); }
|
||||
|
||||
preorder_iterator endPre(void)
|
||||
{ return tree<void*>::endPre(); }
|
||||
|
||||
const_preorder_iterator endPre(void) const
|
||||
{ return tree<void*>::endPre(); }
|
||||
|
||||
iterator getRoot(void)
|
||||
{ return tree<void*>::getRoot(); }
|
||||
|
||||
const_iterator getRoot(void) const
|
||||
{ return tree<void*>::getRoot(); }
|
||||
|
||||
iterator setRoot(N* root_data)
|
||||
{ return tree<void*>::setRoot(root_data); }
|
||||
};
|
||||
|
||||
#if 0
|
||||
template class tree<void*>;
|
||||
template class tree<void*>::tree_node<void*>;
|
||||
|
||||
template <class N>
|
||||
class tree<N*> : public tree<void*>
|
||||
{
|
||||
public:
|
||||
|
||||
// class const_iterator;
|
||||
|
||||
private:
|
||||
|
||||
template <class T>
|
||||
class tree_node<T*> : public tree_node<void*>
|
||||
{
|
||||
public:
|
||||
|
||||
tree_node(void) : tree_node<void*>() { }
|
||||
|
||||
tree_node(T* data) : tree_node<void*>(data) { }
|
||||
};
|
||||
/*
|
||||
template <class T, class R, class P>
|
||||
class tree_iterator<T*, R*, P*> : public tree_iterator<void*, void*&, void**>
|
||||
{
|
||||
|
||||
};
|
||||
*/
|
||||
public:
|
||||
|
||||
tree(void) : tree<void*>()
|
||||
{
|
||||
std::cout << "specialized tree default constructor" << std::endl;
|
||||
}
|
||||
|
||||
explicit tree(N* root_data) : tree<void*>(root_data)
|
||||
{
|
||||
}
|
||||
};
|
||||
/*
|
||||
template<class N>
|
||||
class tree<N*>::iterator : public tree<N>::template tree_iterator<N*, N&, N*>
|
||||
{
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
template <class N>
|
||||
class tree<N*>::const_iterator : public tree<void*>::iterator
|
||||
{
|
||||
private:
|
||||
|
||||
/* this typedef is very convenient and allows Java-like code */
|
||||
typedef typename tree<N*>::template tree_iterator<N*, const N*&, const N**> super;
|
||||
|
||||
public:
|
||||
|
||||
typename super::reference
|
||||
operator * (void) const { return this->current->data; }
|
||||
};
|
||||
|
||||
//template <class N*>
|
||||
//typename tree<N*>::template tree_iterator<N*, const N*&, const N**>::reference
|
||||
//tree<N*>::template const_iterator::operator * (void) const
|
||||
//{ return this->current->data; }
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} /* namespace taj */
|
||||
|
||||
#undef TREE_MASTER_INVARIANT
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
template<class N>
|
||||
template<class T, class R, class P>
|
||||
void tree<N>::tree_iterator<T, R, P>::post_inc(tree_node<N>*& current, long& depth)
|
||||
{
|
||||
assert(current != NULL);
|
||||
|
||||
if (current->next_sibling == NULL)
|
||||
{
|
||||
current = current->parent;
|
||||
depth--;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = current->next_sibling;
|
||||
while (current->first_child != NULL)
|
||||
{
|
||||
current = current->first_child;
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class N>
|
||||
template<class T, class R, class P>
|
||||
void tree<N>::tree_iterator<T, R, P>::post_dec(tree_node<N>*& current, long& depth)
|
||||
{
|
||||
assert(current != NULL);
|
||||
|
||||
if(current->last_child == NULL)
|
||||
{
|
||||
while (current->prev_sibling == NULL)
|
||||
{
|
||||
current = current->parent;
|
||||
depth--;
|
||||
}
|
||||
|
||||
current = current->prev_sibling;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = current->last_child;
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
template<class N>
|
||||
template<class T, class R, class P>
|
||||
void tree<N>::tree_iterator<T, R, P>::pre_inc(tree_node<N>*& current, long& depth)
|
||||
{
|
||||
assert(current != NULL);
|
||||
|
||||
if (current->first_child != NULL)
|
||||
{
|
||||
current = current->first_child;
|
||||
depth++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (current->next_sibling == NULL)
|
||||
{
|
||||
current = current->parent;
|
||||
depth--;
|
||||
if (current == NULL)
|
||||
return;
|
||||
}
|
||||
current = current->next_sibling;
|
||||
}
|
||||
}
|
||||
|
||||
template<class N>
|
||||
template<class T, class R, class P>
|
||||
void tree<N>::tree_iterator<T, R, P>::pre_dec(tree_node<N>*& current, long& depth)
|
||||
{
|
||||
assert(current != NULL);
|
||||
|
||||
if (current->prev_sibling)
|
||||
{
|
||||
current = current->prev_sibling;
|
||||
while (current->last_child != NULL)
|
||||
{
|
||||
current = current->last_child;
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
current = current->parent;
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
|
||||
template<class N>
|
||||
template<class T, class R, class P>
|
||||
inline void tree<N>::tree_iterator<T, R, P>::sib_inc(tree_node<N>*& current)
|
||||
{
|
||||
if (current != NULL)
|
||||
current = current->next_sibling;
|
||||
}
|
||||
|
||||
template<class N>
|
||||
template<class T, class R, class P>
|
||||
inline void tree<N>::tree_iterator<T, R, P>::sib_dec(tree_node<N>*& current)
|
||||
{
|
||||
if (current != NULL)
|
||||
current = current->prev_sibling;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** The base template for all iterators.
|
||||
*/
|
||||
template <class T, class R, class P>
|
||||
class tree_iterator
|
||||
{
|
||||
friend class tree;
|
||||
|
||||
protected:
|
||||
|
||||
/* The node pointed to by this iterator. */
|
||||
tree_node<N>* current;
|
||||
|
||||
/* This is the depth of an iterator relative to its starting position.
|
||||
The starting depth is 0, the depth of the parent is -1, the depth
|
||||
of any child is 1, the depth of any grandchild is 2, etc. */
|
||||
long iter_depth;
|
||||
|
||||
/** Allows derived classes to create an iterator
|
||||
* from a pointer to a node. This constructor
|
||||
* is not explicit because the tree_iterator class
|
||||
* contains the == and != operators, which are used
|
||||
* throughout the template to compare iterators
|
||||
* to NULL. The tree_iterator class is not visible
|
||||
* to the user, so this implicit constructor is
|
||||
* entirely for my convenience when coding the template.
|
||||
*
|
||||
* @param current Position for the new iterator
|
||||
*/
|
||||
tree_iterator(tree_node<N>* current) : current(current), iter_depth(0L) { }
|
||||
|
||||
/** Destroys the node pointed to by this iterator.
|
||||
*/
|
||||
void destroy(void)
|
||||
{
|
||||
delete current;
|
||||
current = NULL;
|
||||
iter_depth = 0L;
|
||||
}
|
||||
|
||||
/* increment and decrement methods used by both the iterator
|
||||
and the const_iterator versions of various iterators */
|
||||
|
||||
static inline void post_inc(tree_node<N>*& current, long& depth);
|
||||
static inline void post_dec(tree_node<N>*& current, long& depth);
|
||||
|
||||
static inline void pre_inc(tree_node<N>*& current, long& depth);
|
||||
static inline void pre_dec(tree_node<N>*& current, long& depth);
|
||||
|
||||
static inline void sib_inc(tree_node<N>*& current);
|
||||
static inline void sib_dec(tree_node<N>*& current);
|
||||
|
||||
public:
|
||||
|
||||
/* The following typedefs are required for compatibility
|
||||
* with standard containers. */
|
||||
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef R reference;
|
||||
typedef P pointer;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
tree_iterator(void) : current(NULL), iter_depth(0L) { }
|
||||
|
||||
tree_iterator(const tree_iterator& iter)
|
||||
: current(iter.current), iter_depth(iter.iter_depth) { }
|
||||
|
||||
/* note that depth is not relevant when comparing iterators */
|
||||
|
||||
bool operator == (const tree_iterator& iter) const
|
||||
{ return this->current == iter.current; }
|
||||
|
||||
bool operator != (const tree_iterator& iter) const
|
||||
{ return this->current != iter.current; }
|
||||
|
||||
long depth(void) const { return iter_depth; }
|
||||
|
||||
bool leaf(void) const { return this->first_child == NULL; }
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** Provides a tree node used internally by the tree template. Overhead added
|
||||
* to the user's node type is only five pointers, so 20 additional bytes on a
|
||||
* 32-bit machine.
|
||||
*/
|
||||
template <class T>
|
||||
class tree_node
|
||||
{
|
||||
public:
|
||||
|
||||
T data;
|
||||
|
||||
tree_node *parent;
|
||||
tree_node *first_child, *last_child;
|
||||
tree_node *prev_sibling, *next_sibling;
|
||||
|
||||
tree_node(void) { }
|
||||
|
||||
tree_node(const T& data) : data(data) { }
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006, Troy Aaron Johnson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Troy Aaron Johnson nor the names of any
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "tree.h"
|
||||
|
||||
using namespace taj;
|
||||
|
||||
bool pruning_predicate(const tree<std::string>::iterator& node)
|
||||
{
|
||||
return (*node == "B");
|
||||
}
|
||||
|
||||
template <class TreeType>
|
||||
void print(const tree<TreeType>& t)
|
||||
{
|
||||
std::cout << "preorder traversal: " << std::endl;
|
||||
for (typename tree<TreeType>::const_preorder_iterator i = t.beginPre(); i != t.endPre(); ++i)
|
||||
{
|
||||
std::cout << *i << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "postorder traversal: " << std::endl;
|
||||
for (typename tree<TreeType>::const_postorder_iterator i = t.beginPost(); i != t.endPost(); ++i)
|
||||
{
|
||||
std::cout << *i << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "bfs traversal: " << std::endl;
|
||||
for (typename tree<TreeType>::const_bfs_iterator i = t.beginBfs(); i != i.endBfs(); ++i)
|
||||
{
|
||||
std::cout << *i << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void pointer_specialization_test(void)
|
||||
{
|
||||
tree<int*> pint_tree;
|
||||
|
||||
int x = 1, y = 2, z = 3;
|
||||
|
||||
tree<int*>::iterator i(pint_tree.setRoot(&x));
|
||||
|
||||
i.push_back(&y);
|
||||
i.push_back(&z);
|
||||
|
||||
std::cout << "int* tree root is " << **i << std::endl;
|
||||
|
||||
tree<int*>::sibling_iterator si(i.beginChildren());
|
||||
|
||||
tree<char*> t1;
|
||||
tree<long*> t2;
|
||||
tree<float*> t3;
|
||||
tree<double*> t4;
|
||||
tree<std::string*> t5;
|
||||
tree<unsigned char*> t6;
|
||||
tree<unsigned long*> t7;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
tree<std::string> t;
|
||||
|
||||
assert(t.empty());
|
||||
assert(t.size() == 0);
|
||||
|
||||
tree<std::string>::sibling_iterator i(t.setRoot("root"));
|
||||
|
||||
assert(!t.empty());
|
||||
assert(t.size() == 1);
|
||||
assert(*i == "root");
|
||||
|
||||
*i = "new root";
|
||||
|
||||
assert(*i == "new root");
|
||||
|
||||
tree<std::string>::sibling_iterator j(i.push_back("left"));
|
||||
assert(t.size() == 2);
|
||||
tree<std::string>::sibling_iterator k(i.push_back("right"));
|
||||
assert(t.size() == 3);
|
||||
|
||||
assert(*j == "left");
|
||||
assert(*k == "right");
|
||||
|
||||
j.push_back("A");
|
||||
j.push_back("B");
|
||||
|
||||
k.push_back("C");
|
||||
k.push_back("D");
|
||||
|
||||
assert(find(t.beginPre(), t.endPre(), "C") != t.endPre());
|
||||
assert(find(t.beginPre(), t.endPre(), "Z") == t.endPre());
|
||||
|
||||
std::cout << "tree height is " << t.height() << std::endl;
|
||||
|
||||
print(t);
|
||||
|
||||
tree<std::string> copy_of_t(t);
|
||||
|
||||
print(copy_of_t);
|
||||
|
||||
std::list<int> int_list;
|
||||
for (int i = 1; i < 20; ++i)
|
||||
int_list.push_back(i);
|
||||
|
||||
tree<int> int_tree(int_list.begin(), int_list.end(), 2);
|
||||
|
||||
print(int_tree);
|
||||
|
||||
pointer_specialization_test();
|
||||
}
|
||||
Reference in New Issue
Block a user