Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar...

16
Data Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially used to store and organize data where the relationship among data is linear or one-dimensional (a circular structure can be considered as a special case of a linear structure). A lot of data is however non-linear in nature. Examples of such data include hierarchical data organizations such as lineal charts, file directories, and table of contents of a book. Figure… shows one such hierarchy which presents a section of the family tree of perhaps the most famous Arab tribe Banu- Quresh, highlighting lineage of the Holy Prophet Muhammad (PBUH). Such hierarchical organizations are very common and cannot be expressed with linear lists. We therefore need other data structures to model such organizations. Tree is perhaps the most important non-linear data structure with numerous applications in computing and other fields. This chapter is dedicated to the discussion of tree data structure. 5.1 Tree – some definitions The elements of a tree are called nodes. A tree consists of a finite set of nodes and links. A link connects two nodes of a tree. Two nodes are said to be adjacent if they are directly connected by a link. A path is a sequence of adjacent nodes. Every node is connected to every other node in the tree through a unique path. A tree which does not have any node is called an empty tree. Our focus of interest is a special kind of tree called the rooted tree. A rooted tree is a non-empty tree which has a specially designated node called the root node. By convention, rooted trees are shown to grow downwards with the root node shown at the top and serves as start or the entry point in to the tree. All other nodes are said to be descendents of the root node. The direct descendents (nodes that have a direct link) of a node are called its children and the node itself is called the parent of those nodes. Children of the same node are called siblings. The root node does not have any parent. Every other node has exactly one parent. A node may have 0 or

Transcript of Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar...

Page 1: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 1 of 16

Chapter 5 Trees – Introduction

Linked-lists are essentially used to store and organize data where the

relationship among data is linear or one-dimensional (a circular structure

can be considered as a special case of a linear structure). A lot of data is

however non-linear in nature. Examples of such data include hierarchical

data organizations such as lineal charts, file directories, and table of

contents of a book. Figure… shows one such hierarchy which presents a

section of the family tree of perhaps the most famous Arab tribe Banu-

Quresh, highlighting lineage of the Holy Prophet Muhammad (PBUH).

Such hierarchical organizations are very common and cannot be

expressed with linear lists. We therefore need other data structures to

model such organizations. Tree is perhaps the most important non-linear

data structure with numerous applications in computing and other fields.

This chapter is dedicated to the discussion of tree data structure.

5.1 Tree – some definitions

The elements of a tree are called nodes. A tree consists of a finite set of

nodes and links. A link connects two nodes of a tree. Two nodes are said

to be adjacent if they are directly connected by a link. A path is a

sequence of adjacent nodes. Every node is connected to every other node

in the tree through a unique path. A tree which does not have any node is

called an empty tree. Our focus of interest is a special kind of tree called

the rooted tree. A rooted tree is a non-empty tree which has a specially

designated node called the root node.

By convention, rooted trees are shown to grow downwards with the root

node shown at the top and serves as start or the entry point in to the tree.

All other nodes are said to be descendents of the root node. The direct

descendents (nodes that have a direct link) of a node are called its

children and the node itself is called the parent of those nodes. Children

of the same node are called siblings. The root node does not have any

parent. Every other node has exactly one parent. A node may have 0 or

Page 2: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 2 of 16

Taie

m

Auf

Hu

sa

isS

ehm

Taie

m

Zah

ra

Mug

hee

ra

Mutlib

Ab

du

s S

ha

ms

Nau

fil

Asad

Nuzla

h

Ha

ris

Zu

ba

irA

bu

Talib

Mu

ha

mm

ad

(PB

UH

)

Ab

du

llah

Musa'a

bA

bu

La

hab

Maq

oom

Ha

jlA

bb

as

Mug

hee

raH

am

za

Za

rrar

Ab

du

l M

utl

ibA

ba

' S

aifi

Ha

sh

imA

bu

Am

rA

bu

Ub

aid

a

Ab

d M

un

af

Ab

du

d D

ar

Ab

du

l U

za

Qu

sa

yy

Kil

ab

Makh

zo

om

Mu

rrah

Ja

mha

Adi

Ka

'ab

Am

irH

irs

Lu

ayy

Gh

ali

bM

uh

ari

b

Qu

resh

Page 3: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 3 of 16

more children. A node with zero children is called a leaf node. Nodes

other than the leaf nodes and the root node are called internal or

intermediate nodes. That is, an intermediate node has exactly one parent

and at least one child.

A subset of a tree that can be viewed as a complete tree in itself is called a

subtree. That is, a node with all its descendents is a subtree. In other

words, every node in a tree can be seen as the root node of the subtree

rooted at that node. The subtree corresponding to the root node is the

entire tree and hence a tree is defined and identified by its root node.

Figure … shows a rooted tree with root A with nodes B, F, and K as its

children/subtrees. Nodes B, F, K , C, D, and X are internal nodes whereas

H, L, Q, G, M, I, N, and P are leaf nodes.

Degree of a node is defined as the number of children of that node. In

Figure…, nodes H, L, Q, G, M, I, N, and P have degree 0, nodes F and X

have degree 1, nodes B, K, and D have degree 2, and A and C have degree

3.

Level of a node is defined as the distance of the node from the root node.

In Figure … A is at level 0, B, F, and K are at level 1, C, H, D, L and X are

level 2, and the rest are at level 3.

Height of a tree is defined as the maximum level of any node in the tree1.

Height of tree in Figure… is 3.

1 Definition of height and level is not standardized and may slightly vary from one text to the other.

Page 4: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 4 of 16

5.2 Binary tree

A binary tree is a special kind of rooted tree with the property that all

nodes in a binary tree have at most two children. That is, the maximum

degree of a node in a binary tree is 2. The two children of a node in a

binary tree are usually designated as the left and right child.

A binary tree can be defined recursively as the following:

a) A binary tree is either empty or non-empty

b) If the binary tree is non-empty then

1. There is a root node

2. The root node has two children, the left child and the right child.

These children correspond to two subtrees – the left subtree and

the right subtree.

3. Each subtree is a binary tree.

Figure… (a) and (b) are examples of binary trees. In Figure…(a), B is the

left child of A and H is the right child of B.

It can be very easily seen that the maximum number of nodes on level i of

a binary tree is 2i and the maximum number of nodes in a binary tree of

height k is 2k+1 – 1.

A binary tree of height k having 2k+1 – 1 nodes is called a full binary tree.

A binary tree is a full binary tree if and only if all leaf nodes are at the

same level and all other nodes have degree 2. Figure… shows a full binary

tree of height 4 with 15 nodes in it.

Page 5: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 5 of 16

A complete binary tree is a binary tree that is completely filled, with the

possible exception of the bottom level, which is filled from left to right.

Another way to determine whether a tree is complete or not is to assign

numbers to all its nodes as follows:

1. root node is assigned number 1.

2. for a node numbered i, assign 2*i and 2*i + 1 to its left and right

children respectively.

then the tree is a complete binary tree iff the maximum number thus

assigned is equal to the number of nodes in the tree. Note that full binary

tree is also a complete binary tree.

Figure… (a) is an example of a complete binary tree whereas the tree in

Figure…(b) is not complete.

Page 6: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 6 of 16

5.3 Binary tree implementation using linked structures

Binary trees can be easily implemented using dynamically created nodes

which are linked through pointers. As shown in Figure…, a binary tree

node structure is quite similar to that of a doubly linked-list – instead of

having pointers to the next and previous nodes, in this case, we have

pointers to the left and right children of the node. Some implementations

also add a pointer to the parent node but in most cases this is not required.

template <class T>

struct TreeNode {

T data;

TreeNode<T> *left, *right;

};

We can now use this node structure to define our binary tree whose

specification is shown in Figure…

template <class T>

class BinaryTree {

public:

BinaryTree(){root = NULL;} // create an empty binary tree

void buildBinaryTree( T data, BinaryTree<T> &leftSubtree,

BinaryTree<T> &rightSubtree);

/*************************************************************

This method can be used to build a binary tree bottoms up. The

modified tree is rooted at a node with the input data and its

left and right children are made-up of the left and right

subtrees passed as input parameters. The left and right

subtrees passed as input lose their contents and their roots

are set to NULL.

**************************************************************/

~BinaryTree(){clear(root);}

void inOrder(){inOrder(root);} // in-order traversal

void preOrder(){inOrder(root);} // pre-order traversal

void postOrder(){inOrder(root);} // post-order traversal

BinaryTree(const BinaryTree & bt); // copy constructor

const BinaryTree & operator=(const BinaryTree & rhs);

// assignment operator

private:

TreeNode <T> *root;

friend class LNRIterator<T>; // in-order iterator

TreeNode<T> * createTreeNode(T data);

void clear(TreeNode<T> *t); // cleanup tree

void inOrder(TreeNode<T> *t); // in-order workhorse

void preOrder(TreeNode<T> *t); // pre-order workhorse

void postOrder(TreeNode<T> *t); // post-order workhorse

};

data

left right

Page 7: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 7 of 16

5.3.1 Building a binary tree

Figure… shows the methods to build the binary from bottom to top.

template <class T>

TreeNode<T> * BinaryTree<T> :: createTreeNode(T data) {

TreeNode<T> *t = new TreeNode<T>;

if (t != NULL) {

t->data = data;

t->left = t->right = NULL;

return t;

}

else

throw OUT_OF_MEMORY;

}

template <class T>

void BinaryTree<T> ::

buildBinaryTree(T Data,BinaryTree<T> &leftSubtree,

BinaryTree<T> &rightSubtree) {

// create a new tree node and store data in it

TreeNode<T> *t = createTreeNode(data);

// make the left and right of the new node point to the roots

// of the left and right sub-trees respectively

t->left = leftSubtree->root;

t->right = rightSubtree->root;

// assign NULL to roots of the input trees so that the nodes

// that have now been shifted to the target tree are not

// destroyed when the destructor is called for these trees.

leftSubtree->root = NULL;

rightSubtree->root = NULL;

clear(root); // return any existing nodes in the tree to heap

root = t; // make the new node the root of the target tree

}

There are a couple of points to be noted.

1. This method detaches the nodes present in the trees passed as input

parameters and attaches those nodes to the tree which we are building

from these sub-trees. Hence these trees are effectively destroyed by

assigning NULL value to their roots.

2. The second last statement in the method, clear(root), is very

important. It essentially destroys the target tree by returning any

nodes attached to back to heap. Failing to do so could create garbage.

Page 8: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 8 of 16

Figure …(b to f) demonstrates how this method could be used to build the

tree of Figure….(a).

4

2 5

1 3

(a)

root

NULL

t1

root

NULL

t2

root

NULL

nullTree

(b) BinaryTree<int> t1, t2, nullTree;

root root

t1

1 3

(c) t1.buildTree(1,nullTree, nullTree);

t2.buildTree(3,nullTree, nullTree);

t2

t1.buildTree(2,t1, t2);

root root

t1 t2

NULL2

1 3

(d)

t2

t2.buildTree(5, nullTree, nullTree);

root

5

(e) t1.buildTree(4,t1, t2);

root

t1

root

t2

NULL4

2 5

1 3

(f)

Page 9: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 9 of 16

5.3.2 Binary tree traversal

It is often required to visit (access) each node in the tree and process data

present in there. For that purpose some tree traversal algorithm is used

which provides a systematic approach to access all the nodes in the tree. A

complete traversal generates a linear order of all the nodes in the tree.

As described in section 5.2, a non-empty tree is defined by the node

pointed to by its root and its two children – the left subtree and the right

subtree. These two subtrees are also trees rooted at the left and right child

of the parent node. A traversal algorithm can be developed easily by

making use of this recursive definition.

Let N, L, and R denote node, left subtree, and right subtree of a tree. As

shown in Figure…, these three letters (N, L, and R) can be arranged in six

different permutations – NLR, NRL, LNR, LRN, RNL, and RLN. These six

permutations correspond to six different traversals of the binary tree. For

example, LNR corresponds to a traversal in which we complete the tree

traversal by first traversing the left subtree, then visiting the node, and

then traversing the right subtree. If we always traverse left before right

then we are left with three possible traversal – NLR, LNR, and LRN.

These three are called pre-order, in-order, and post-order respectively.

C++ code for in-order and pre-order workhorse functions is given in

Figure…

template <class T>

void BinaryTree<T> ::

inOrder(TreeNode<T> *t) {

if (t != NULL) {

inOrder(t->left);

process(t);

inOrder(t->right);

}

}

template <class T>

void BinaryTree<T> ::

preOrder(TreeNode<T> *t) {

if (t != NULL) {

process(t);

preOrder(t->left);

preOrder(t->right);

}

}

N - Node

L

Left subtree

R

Right subtree

NLR – process the node, then traverse the left subtree, then traverse the right subtree

NRL – process the node, then traverse the right subtree, then traverse the left subtree

LNR – traverse the left subtree, then process the node, then traverse the right subtree

LRN – traverse the left subtree, then traverse the right subtree, then process the node

RNL – traverse the right subtree, process the node, then then traverse the left subtree

RLN – traverse the right subtree, then traverse the left subtree, then process the node

Page 10: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 10 of 16

The in-order, pre-order, and post-order traversals can be generated by

drawing the tree and just walking around it – starting from the left of the

root and ending at the right of it. For each node we note when we are on

its left, under it, and on its right. As shown in Figure…, the pre-order, in-

order, and post-order traversals are generated by visiting each node when

we are on the left, under, and right of it respectively.

A

KB

C H L X

PMQ

NLR – visit when at the left of the Node ABCQMHKLXP

LNR – visit when under the Node QCM BHALKXP

LRN – visit when at the right of the Node QMC HBLPXKA

Figure… shows the three tree traversals for an expression tree. Note that

the in-order, pre-order, and post-order traversals generate the expression

in infix, prefix, and postfix respectively.

-

/+

A * D *

FCB E

LNR: A + B * C – D / E * F

NLR: – + A * B C / D * E F

LRN: A B C * + D E F * / –

Page 11: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 11 of 16

5.3.2.1 The destructor

As shown is Figure…, the binary tree destructor uses clear function. As

can be seen easily, clear requires a post-order traversal of the tree. The

resulting code is given in Figure…

template <class T>

void BinaryTree<T> :: clear(TreeNode<T> *t) {

if (t != NULL) {

clear(t->left);

clear(t->right);

delete t;

}

}

Exercise

1. write the copy constructor

2. write the assignment operator

3. write a member function to count the number of nodes in the tree

4. write a member function to count the leaf nodes

5. write a member function to count the nodes with degree 1

6. write a member function to count nodes with degree 2

7. write a member function to calculate the height of the tree

8. write a member function to make a mirror image of the tree

9. write a member function to determine the presence of a key in the

tree.

10. write a function to determine the level of the node containing a given

key. Return -1 if the key is not present.

11. write a member function == which returns true if the two trees are

equal.

12. write a member function that takes a key and prints the entire subtree

rooted at the node that contains the key.

13. write a member function that takes a key and prints the entire subtree

rooted at the sibling of the node that contains the key.

14. write a member function that deletes all the leaf nodes from the tree.

Page 12: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 12 of 16

15. write a member function that deletes all the nodes with degree 1 from

the tree.

16. write a member function that takes two keys as input and inserts a

node with second key as the left most descendent of the node with

the first key if it the first key present in the tree making the new node

the first node to be visited in in-order in the tree rooted at the node

that contains the first key.

17. write a member function that takes two keys as input and inserts a

node with second key as the right most descendent of the node with

the first key if it the first key present in the tree making the new node

the last node to be visited in in-order in the tree rooted at the node

that contains the first key.

Page 13: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 13 of 16

5.4 Tree iterators

Just like the linked-list class, we need tree iterators that would allow us to

access each element of the tree in some order so that we can process data

according to our specific need. Since, for each node reached through the

iterator we process the data in the node and then request for the next

node, we cannot use recursion because once we return from that function,

we cannot restart the recursion from that node – the context (addresses of

the all the ancestors stored on to the implicit stack) would have been lost.

We would therefore need an iterative solution – where, in order to

remember the context, an explicit stack needs to be employed. Following

this line of thought, an in-order iterator for the binary tree class is

developed. The iterator supports the four basic functions – create, isDone,

begin, next, and getData and is presented in Figure….

template <class T>

class LNRIterator {

private:

const BinaryTree<T> &tree; // the associated tree

TreeNode<T> *current; // pointer to the current node

Stack<TreeNode<T> *> stk; // used for storing those

// ancestors of current that are

// yet to be visited

TreeNode<T> * gotoTheLeftmostDescendent(TreeNode<T> *t);

// given a node, go its leftmost descendent

// to be used in begin() and next()

public:

LNRIterator(const BinaryTree<T> &bt):tree(bt), current(NULL){ }

bool isDone() {return current == NULL; }

T getData() {

if (!isDone()) return current->data;

else throw ILLEGAL_REFERNCE_EXCEPTION;

}

void begin(); // takes current to the first node to be visited

void next(); // moves current to the next node in order

};

The constructor, isDone, and getData are trivial and do not need

elaboration. We will therefore only focus on begin and next which are

given in Figure ….

Page 14: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 14 of 16

template <class T>

TreeNode<T> * LNRIterator<T> ::

gotoTheLeftmostDescendent(TreeNode<T> *t)

{

TreeNode<T> *temp = t;

while(temp->left != NULL) {

stk.push(temp);

temp = temp->left;

}

return temp;

}

template <class T>

void LNRIterator<T> :: begin() {

stk.clear();

stk.push(NULL);

current = root;

if (root != NULL) // if the tree is not empty

current = gotoTheLeftmostDescendent(root);

}

Begin sets the value of the current to the first node to be visited in order.

Starting from the root, it gets to the left-most child of the root by keeping

moving to the left until by a node is reached whose left child is not

present. Before moving to the left, address of the node is saved so that it

can be used later for visiting the node and then traversing its right

subtree. It may be noted that begin also initializes the stack by clearing it

of its contents and puts NULL on to it. This will be used to set the value of

current to NULL when the iterator goes beyond the last node.

After visiting a node, the in-order traversal of the right subtree by moving

to its right child and then to the leftmost descendent of the right child

and saving the address of the nodes encountered in the process. This is

like repeating the process similar to begin for the tree rooted at the right

child of a node. Once the traversal on the right is complete, this means

the entire subtree rooted at that node is complete and hence current

moves back one step in the hierarchy by popping the address of its

ancestor. The process continues until NULL is popped from the stack and

assigned to current, indicating end of traversal. The code for the next()

operation is given in Figure…

template <class T>

void LNRIterator<T> :: next() {

if (current == NULL) throw ILLEGAL_REFERENCE_EXCEPTION;

if (current->right != NULL) {

current = gotoTheLeftmostDescendent(current->right);

else current = stk.pop();

}

Page 15: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 15 of 16

We can now use this iterator to for our specific purpose as shown below:

BinaryTree<int> binTree;

// add data to the tree

LNRIterator<int> myIterator(binTree);

for(myIterator.begin(); myIterator.isDone(); myIterator.next())

cout << getData();

Exercise:

1. Write pre-order iterator.

2. write post-order iterator.

3. write iterative stack-based in-order traversal

4. write iterative stack-based pre-order traversal

5. write iterative stack-based post-order traversal

6. write a member function of the in-order iterator class to add a new

node as the leftmost descendent of the current node.

7. Write a function to delete the leftmost descendent of the current

class. Warning: the node to be deleted may have a right child which

must be preserved.

8. write a member function of the in-order iterator class to add a new

node as the rightmost descendent of the current node.

9. Write a function to delete the rightmost descendent of the current

class. Warning: the node to be deleted may have a left child which

must be preserved.

Page 16: Chapter 5 Trees Introduction - Spartans Fall-14 · PDF fileData Structures – Fakhar lodhi – Chapter 5: Trees Page 1 of 16 Chapter 5 Trees – Introduction Linked-lists are essentially

Data Structures – Fakhar lodhi – Chapter 5: Trees

Page 16 of 16

5.5 Level-order traversal

Level-order traversal traverses the tree level by level. That is, it traverses

all the nodes at level i before moving to nodes at level i+1. Such a traversal

is also called depth-first traversal. Traditionally, level-order traversal is

performed top-to-bottom and left-to-tight. For example, level-order

traversal of the tree of Figure… will visit nodes in the following order:

A B K C H L X Q M P

Level-order traversal can be implemented by using a queue. A node at

level i would have its children at level i+1. Therefore, after visiting a

node, if its children were added to the queue, then they could be retrieved

from the queue and visited in their order of insertion, resulting in level-

order traversal.

We start by inserting the root node to the queue. Then we remove a node

from the queue, visit it and put its children, if any, on the queue. The

process continues until there is nothing left on the queue. The code for

level-order traversal is presented in Figure…

template <class T>

void BinaryTree<T> :: levelOrder() {

if (root != NULL) {

TreeNode<T> *t;

Queue<TreeNode<T> *> que;

que.add(root);

while(!que.isEmpty()) {

t = que.remove();

visit(t);

if (t->left != NULL) que.add(t->left);

if (t->right != NULL) que.add(t->right);

}

}

}

Exercise:

1. Write a function that takes a number as input and prints all the nodes

present at that level.

2. Write level-order iterator.

3. Write a recursive function to achieve the task specified in Q. 1