1 Trees 2: Traversals and related matters. 2 Tree traversal traversalAny operation that performs...

Post on 21-Dec-2015

218 views 0 download

Transcript of 1 Trees 2: Traversals and related matters. 2 Tree traversal traversalAny operation that performs...

1

Trees 2:

Traversals and related matters

2

Tree traversal

• Any operation that performs some process on all the nodes in a tree must perform a tree traversaltraversal

• Traversal refers to visiting each node in turn

• Traversal is a recursive process: we visit each node, and we visit each node in the subtree of which the node is the root

3

Now, more ways to climb!

• There are three basic tree traversal patterns, referring to the order in which nodes are visited and processed– Pre-order: visit root, then left subtree, then right– In-order: visit left subtree, then root, then right– Post-order: visit left subtree, then right, then root

4

Example: printing all nodes

// pre-order traversaltemplate <class Item>void print (BTtnode <Item>* root){if (root != NULL){

cout << root->data << endl; // 1print (root->left); // 2print (root->right); // 3

}}

5

Pre-order traversal in action

K

I R

K W O

O D

Original tree: Results:K

IKWROOD

6

Example: printing all nodes

// in-order traversaltemplate <class Item>void print (BTtnode <Item>* root){if (root != NULL){

print (root->left); // 2cout << root->data << endl; // 1print (root->right); // 3

}}

7

In-order traversal in action

K

I R

K W O

O D

Original tree: Results:KI

W

K

RO

OD

8

Example: printing all nodes

// post-order traversaltemplate <class Item>void print (BTtnode <Item>* root){if (root != NULL){

print (root->left); // 2print (root->right); // 3cout << root->data << endl; // 1

}}

9

Post-order traversal in action

K

I R

K W O

O D

Original tree: Results: K

W

I

O

D

O

R

K

10

Backward in-order traversal

• As the previous examples have shown, none of the traversal methods print the nodes in the order in which they’re arranged

• One way to depict the nodes in a tree is by printing it sideways, with the leftmost node being the root, root’s children above and below root on the right, and so on

• This can be accomplished using backward in-order traversal

11

Backward in-order traversal

• The steps are:– process right subtree (recursive call)– process root– process left subtree (recursive call)

• Combine this with the idea of printing spaces for indentation at each new level of the tree, and you get the function on the next slide

12

BTnode print() function

template <class Item>void print(const BTnode<Item>* ptr, int depth){

if (ptr != NULL){

print(ptr->right( ), depth+1);cout << setw(4*depth) << ptr->data << endl;print(ptr->left( ), depth+1);

}}

13

Generalized traversals

• Each of the examples we have seen focused on printing data values in the binary tree nodes

• A more useful traversal function would have the ability to perform any operation on the nodes in a binary tree - to do so, however, requires the introduction of a new concept

14

Functions as parameters

• In C++, we can pass functions (not just function calls) as parameters, provided we set things up correctly

• For example, consider the prototype below:void apply(void f(int&), int data[], int n);

• The first argument to function apply is any function f, which must be a void function with an int reference parameter

15

Functions as parameters

• Implementation of apply function:void apply(void f(int&), int data[], int n)

{

for (int x = 0; x < n; x++)

f(data[x]);

}

• Apply performs function f on every element of array data

16

Examples of calls to apply

• Suppose we have the following functions:void square(int &x) { x *= x; }

void assignRand(int &x) { x = rand() % x; }

• Then we can write calls to apply using the example functions as parameters (assuming array and nums are int arrays):apply (square, array, 200);

apply (assignRand, nums, 50);

17

Template version of apply()

• We can generalize the function further by making it a template function:

template <class Item, class numType>void apply(void f(Item&), Item data[], numType n){

for (int x=0; x < n; x++)f(data[x]);

}

• Function f can now be any void function with a single reference parameter of any type

18

Cautionary note on template version of apply()

• This version does not work with all C++ compilers; it does not work with Turbo C++, Borland C++ version 5.02, or Visual C++ version 6 but doesdoes work with Dev-C++

• Textbook suggests taking generalization a step further, as shown below:template<class Process, class Item, class NumType>void apply(Process f, Item data[], NumType n)… but I couldn’t find a compiler this works with

19

More generalized traversals

• We can apply the lessons learned in creating the apply() function to the task of generalizing the traversal functions

• For example, the preorder() function could be rewritten as shown on the next slide

• Note that this is analogous to the second version of apply(), because this actually works with an available compiler

20

Generalized preorder function

template <class Item, class node>void preorder (void f(Item&), node* ptr){

if (ptr != NULL){

f(ptr->data());preorder(f, ptr->left);preorder(f, ptr->right);

}}

21

Trees 2:

Traversals and related matters

- ends -