Trees 2: Dynamic Binary Tree Navigation and Iteration Andy Wang

advertisement
Trees 2: Dynamic Binary
Tree Navigation and
Iteration
Andy Wang
Data Structures, Algorithms, and
Generic Programming
Trees 2: Overview



Dynamic memory implementation of
binary trees
Binary tree navigators
Binary tree iterators
Dynamic Memory
Implementation of Binary
Trees



Similar to dynamic memory
implementation of List
Use a structural class TNode
TNode has three pointers
– parent
– lchild
– rchild
Dynamic Memory
Implementation of Binary
Trees

TNode has one data field
– value

The three pointer fields allow
navigation through the tree
– up
– down-left
– down-right
Non-Object-Based
Approach: Operate Directly
on Public TNode<T>
template <class T>
class TNode {
public:
T value;
TNode *parent;
*lchild;
*rchild
TNode(const T& t) : value(t),
parent(0), lchild(0), rchild(0) { }
};
Non-Object-Based Recursive
Traversal Algorithms for
TNode<T>
void inorder(TNode<T>* root, void (TNode<T>*) visit) {
if (root == 0) {
return;
}
inorder(root->lchild, visit);
visit(root);
inorder(root->rchild, visit);
}
void preorder(TNode<T>* root, void (TNode<T>*) visit) {
if (root == 0) {
return;
}
visit(root);
inorder(root->lchild, visit);
inorder(root->rchild, visit);
}
Non-Object-Based Recursive
Traversal Algorithms for
TNode<T>
void postorder(TNode<T>* root, void (TNode<T>*) visit) {
if (root == 0) {
return;
}
inorder(root->lchild, visit);
inorder(root->rchild, visit);
visit(root);
}
An Object-Based
Approach





Generic pContainer TBinaryTree<T>
Restrict access to data
Make external algorithms object-based
Model: TList<T>
Define iterators
– Allow stopping in mid-traversal
– Allow multiple iterators for a single
container
An Object-Based
Approach

Define navigators
– Allow navigation within a tree structure
– Use to implement tree iterator methods
and other algorithms

When a recursive method
implementation is appropriate, make
the method protected
Object-Based
Implementation
template <typename T>
class TBinaryTree {
class TNode {
T value;
TNode *parent,
*lchild;
*rchild;
TNode(const T& t);
friend class TBinaryTree<T>;
friend class TBinaryTreeNavigator<T>;
};
protected:
TNode *root;
Object-Based
Implementation
public:
typedef T value_type;
typedef TBinaryTreeNavigator<T> Navigator;
typedef TBinaryTreeInorderIterator<T> Iterator;
.. other iterator types as needed
};
Binary Tree Navigators


Analogous to list iterators
Use tree structure to navigate
– N.initialize(B) sets N at the root of B
– ++N moves N down to its left childe
– N++ moves N down to its right child
– --N or N-- moves N up to its parent

Navigator used to implement tree
iterator types
Binary Tree Navigators

Not the same as the tree Iterators!
– Navigators: physical traversals
Binary Tree Navigators

Not the same as the tree Iterators!
– Iterators: logical traversals
– Navigator used to implement tree iterator
types
Defining class
TBinaryTreeNavigator
template <typename T>
class TBinaryTreeNavigator {
private:
TBinaryTree<T>::TNode *currNode;
public:
T& Retrieve() const;
int Valid() const;
int HasParent() const;
int HasLeftChild() const;
int HasRightChild() const;
int IsLeftChild() const;
int IsRightChild() const;
// various operators:
};
==, !=, *, =, ++, --,
Implementing class
TBinaryTreeNavigator<T>
template <typename T>
int TBinaryTreeNavigator<T>::HasParent() const {
return (currNode != 0 && currNode->parent != 0);
}
template <typename T>
int TBinaryTreeNavigator<T>::HasLeftChild() const {
return (currNode != 0 && currNode->lchild != 0);
}
template <typename T>
int TBinaryTreeNavigator<T>::IsLeftChild() const {
return (currNode != 0 && currNode->parent != 0 &&
currNode == currNode->parent->lchild);
}
Implementing class
TBinaryTreeNavigator<T>
template <typename T>
int TBinaryTreeNavigator<T>::Valid() const {
return (currNode != 0);
}
template <typename T>
T& TBinaryTreeNavigator<T>::Retrieve() const {
if (currNode == 0) { // error }
return (currNode->value);
}
template <typename T>
TBinaryTreeNavigator<T>& TBinaryTreeNavigator<T>::operator ++() {
if (currNode != 0) { currNode = currNode->lchild; }
return *this;
}
Implementing class
TBinaryTreeNavigator<T>
template <typename T>
TBinaryTreeNavigator<T>& TBinaryTreeNavigator<T>::operator ++(int) {
if (currNode != 0) { currNode = currNode->rchild; }
return *this;
}
template <typename T>
TBinaryTreeNavigator<T>& TBinaryTreeNavigator<T>::operator --() {
if (currNode != 0) { currNode = currNode->parent; }
return *this;
}
Inorder Iterator
template <typename T>
class TBinaryTreeInorderIterator {
private:
TBinaryTreeNavigator<T> N;
public:
typedef T value_type;
TBinaryTreeInorderIterator();
~TBinaryTreeInorderIterator();
TBinaryTreeInorderIterator(const TBinaryTreeInorderIterator& I);
TBinaryTreeInorderIterator(const TBinaryTree<T>& B);
TBinaryTreeInorderIterator(const TBinaryTreeNavigator<T> &N);
void Initialize(const TBinaryTree<T>& T);
void rInitialize(const TBinaryTree<T>& T);
Inorder Iterator
T& Retrieve() const;
int Valid() const;
T& Retrieve() const;
int Valid() const;
int operator==(const TBinaryTreeInorderIterator& I2) const;
int operator!=(const TBinaryTreeInorderIterator& I2) const;
T& operator*() const;
TBinaryTreeInorderIterator<T>& operator=(const
TBinaryTreeInorderIterator& I);
TBinaryTreeInorderIterator<T>& operator++();
TBinaryTreeInorderIterator<T> operator++(int);
TBinaryTreeInorderIterator<T>& operator--();
TBinaryTreeInorderIterator<T> operator--(int);
};
Inorder Iterator
Initialization
template <typename T>
void TBinaryTreeInorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
// slide to leftmost node
while (N.HasLeftChild()) {
++N;
}
N
root
1
}
4
2
3
5
6
7
Inorder Iterator
Initialization
template <typename T>
void TBinaryTreeInorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
// slide to leftmost node
while (N.HasLeftChild()) {
++N;
}
root
1
}
N
4
2
3
5
6
7
Inorder Iterator
Initialization
template <typename T>
void TBinaryTreeInorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
// slide to leftmost node
while (N.HasLeftChild()) {
++N;
}
root
1
}
N
4
2
3
5
6
7
Inorder Iterator
Incrementation
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
N
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
N
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
N
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
N
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
root
Inorder Iterator
Incrementation
1
2
4
5
3
N
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
root
Inorder Iterator
Incrementation
1
2
4
5
3
N
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
N
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
N
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
N
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
N
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Inorder Iterator
Incrementation
root
2
1
N
3
4
5
6
7
template <typename T>
TBinaryTreeInorderIterator<T>&
TBinaryTreeInorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
if (N.HashRightChild()) { // slide down the left subtree of the right
// child
N++;
while (N.HasLeftChild()) { ++N; }
} else { // back up to the first ancestor not already visited
int NwasRightChild;
do { // back up once if in a left branch; all the way, if in a
// right branch
NwasRightChild = N.IsRightChild();
--N;
} while (NwasRightChild);
return *this;
}
}
Postorder Iterator
template <typename T>
class TBinaryTreePostorderIterator {
private:
TBinaryTreeNavigator<T> N;
public:
typedef T value_type;
TBinaryTreePostorderIterator();
~TBinaryTreePostorderIterator();
TBinaryTreePostorderIterator(const TBinaryTreePostorderIterator& I);
TBinaryTreePostorderIterator(const TBinaryTree<T>& B);
TBinaryTreePostorderIterator(const TBinaryTreeNavigator<T> &N);
void Initialize(const TBinaryTree<T>& T);
void rInitialize(const TBinaryTree<T>& T);
Postorder Iterator
T& Retrieve() const;
int Valid() const;
T& Retrieve() const;
int Valid() const;
int operator==(const TBinaryTreePostorderIterator& I2) const;
int operator!=(const TBinaryTreePostorderIterator& I2) const;
T& operator*() const;
TBinaryTreePostorderIterator<T>& operator=(const
TBinaryTreePostorderIterator& I);
TBinaryTreePostorderIterator<T>& operator++();
TBinaryTreePostorderIterator<T> operator++(int);
TBinaryTreePostorderIterator<T>& operator--();
TBinaryTreePostorderIterator<T> operator--(int);
};
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
}
}
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
}
}
N
root
1
3
6
7
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
}
}
1
root
N
3
6
7
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
}
}
1
root
N
3
6
7
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
}
}
1
root
3
N
6
7
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
}
}
1
root
3
N
6
7
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
}
}
N
4
root
1
2
3
5
6
7
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
}
}
root
N
4
1
2
3
5
6
7
Postorder Iterator
Initialization
template <typename T>
void TBinaryTreePostorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
// enter tree at root
N = B.Root();
int finished = !N.Valid();
while (!finished) {
if (N.HasLeftChild()) {
++N;
} else if (N.HasRightChild()) {
N++;
} else {
finished = 1;
}
N
}
}
root
4
1
2
3
5
6
7
Postorder Iterator
Incrementation
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
N
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
N
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
N
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
4
root
1
2
5
3
N
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
4
root
1
2
5
3
N
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
4
root
1
2
5
3
N
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
N
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
N
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
N
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
N
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
1
2
3
N
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
N
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Postorder Iterator
Incrementation
root
2
1
N
3
4
5
6
7
template <typename T>
TBinaryTreePostorderIterator<T>&
TBinaryTreePostorderIterator<T>::operator ++() {
if (!N.Valid()) { return *this; }
int NwasLeftChild = N.IsLeftChild();
--N;
if (NwasLeftChild && N.HasRightChild()) {
N++;
// go to the left most node of the left branch, or the left most
// node of the right branch.
}
return *this;
}
Preorder Iterator
template <typename T>
class TBinaryTreePreorderIterator {
private:
CStack<fsu::TBinaryTree<T>::Navigator,
TDeque<TBinaryTree<T>::Navigator> Stk;
TBinaryTreePreorderIterator(const TBinaryTreePreorderIterator& I);
void rInitialize(const TBinaryTree<T>& T);
TBinaryTreePreorderIterator<T>& operator=(const
TBinaryTreePreorderIterator& I);
TBinaryTreePreorderIterator<T>& operator++(int);
TBinaryTreePreorderIterator<T> operator--();
TBinaryTreePreorderIterator<T>& operator--(int);
Preorder Iterator
public:
typedef T value_type;
TBinaryTreePreorderIterator();
TBinaryTreePreorderIterator(const TBinaryTree<T>& L);
virtual ~TBinaryTreePreorderIterator();
void Initialize(const TBinaryTree<T>& T);
T& Retrieve() const;
int Valid() const;
int operator==(const TBinaryTreePreorderIterator& I2);
int operator!=(const TBinaryTreePreorderIterator& I2);
T& operator*() const;
TBinaryTreePreorderIterator<T>& operator++();
};
root
Preorder Iteartor
Initialization
4
1
2
3
5
6
7
template <typename T>
void TBinaryTreePreorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
Stk.Clear();
if (!B.Empty()) {
Stk.Push(B.Root());
}
}
template <typename T>
T& TBinaryTreePreorderIterator<T>::operator*() const {
if (!Stk.Empty()) {
return *(Stk.Top());
}
}
1
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
Preorder Iteartor
Incrementation
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
1
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
2
1
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
2
1
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
2
1
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
4
2
1
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
4
2
1
root
Preorder Iteartor
Incrementation
4
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
1
2
3
5
6
7
4
2
}
1
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
2
}
1
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
2
}
1
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
1
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
5
}
1
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
5
}
1
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
5
}
1
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
1
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
1
root
Preorder Iteartor
Incrementation
4
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
1
2
3
5
6
7
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
3
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
3
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
3
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
6
3
root
Preorder Iteartor
Incrementation
template <typename T>
TBinaryTreePreorderIterator<T>&
TBinaryTreePreorderIterator<T>::operator++() {
TBinaryTree<T>::Navigator child;
if (!Stk.Empty()) {
// push left child of top if possible
if (Stk.Top().HasLeftChild()) {
Stk.Push(++Stk.Top());
return *this;
}
4
1
2
3
5
6
7
6
3
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
6
}
3
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
3
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
3
root
Preorder Iteartor
Incrementation
4
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
1
2
3
5
6
7
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
7
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
7
root
Preorder Iteartor
Incrementation
4
1
2
3
5
6
7
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
7
root
Preorder Iteartor
Incrementation
4
// otherwise pop until a right child is found
// and push that child onto stack
TBinaryTree<T>::Navigator current;
while (!Stk.Empty()) {
current = Stk.Top();
Stk.Pop();
if (current.HasRightChild()) {
Stk.Push(current++);
return *this;
}
}
}
return *this;
}
1
2
3
5
6
7
Levelorder Iterator
template <typename T>
class TBinaryTreeLevelorderIterator {
private:
CQueue<fsu::TBinaryTree<T>::Navigator,
TDeque<TBinaryTree<T>::Navigator> Que;
TBinaryTreeLevelorderIterator(const TBinaryTreePreorderIterator& I);
void rInitialize(const TBinaryTree<T>& T);
TBinaryTreeLevelorderIterator<T>& operator=(const
TBinaryTreeLevelorderIterator& I);
TBinaryTreeLevelorderIterator<T>& operator++(int);
TBinaryTreeLevelorderIterator<T> operator--();
TBinaryTreeLevelorderIterator<T>& operator--(int);
Levelorder Iterator
public:
typedef T value_type;
TBinaryTreeLevelorderIterator();
TBinaryTreeLevelorderIterator(const TBinaryTree<T>& L);
virtual ~TBinaryTreeLevelorderIterator();
void Initialize(const TBinaryTree<T>& T);
T& Retrieve() const;
int Valid() const;
int operator==(const TBinaryTreeLevelorderIterator& I2);
int operator!=(const TBinaryTreeLevelorderIterator& I2);
T& operator*() const;
TBinaryTreeLevelorderIterator<T>& operator++();
};
Levelorder Iteartor
Initialization
4
root
1
2
3
5
6
1
template <typename T>
void
TBinaryTreeLevelorderIterator<T>::Initialize(const TBinaryTree<T>& B) {
Que.Clear();
if (!B.Empty()) {
Que.Push(B.Root());
}
}
template <typename T>
T& TBinaryTreeLevelorderIterator<T>::operator*() const {
if (!Que.Empty()) {
return *(Que.Front());
}
}
7
Levelorder Iteartor
Incrementation
template <typename T>
TBinaryTreeLevelorderIterator<T>&
TBinaryTreeLevelorderIterator<T>::operator++() {
if (!Que.Empty()) {
if (Que.Front().HasLeftChild()) {
Que.Push(++Que.Front());
}
if (Que.Front().HasRightChild()) {
Que.Push(Que.Front()++);
}
Que.Pop();
}
return *this;
}
Download