You are on page 1of 72

Trees

Part of this lecture was organized by the instructors at the University of Manitoba in Canada and has been modified by Dr. Ahmad Reza Hadaegh
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 1

Trees
A tree is a linked data structure which reflects some hierarchical structure There are several varieties of trees Each with its own characteristics A family of related data structures

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page

Trees
A tree gets its name from its structure which is tree-like A tree has a root, branches, leaves

Root node

A C F I G

Branches

B E

D H

J
Page 3

Leaf nodes
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University

Trees
A tree consists of a number of connected nodes The nodes are organized in a top-down hierarchical manner

A tree is an instance of a general structure called a graph A graph consists of vertices (nodes) and edges (branches), but is not necessarily hierarchical in nature Sometimes tree and graph terminology is interchanged

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page

Trees
A B

C
F I G

D H J

This tree has 10 nodes, 9 branches, 1 root node, and 6 leaf nodes

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page

Trees
Other defining characteristics If node A points to node B, then A is the parent of B Furthermore, B is the child of A Children of the same parent are siblings All nodes beneath a given node (children, children of children, ) are descendants of that node All nodes on the path between the root and a given node are ancestors of that node

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page

Trees
A B E F I The parent of G is D and the parent of E is B The children of A are B, C, and D B, C, and D are sibling The ancestors of J are G, D, and A The descendants of D are G, H, I and J
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 7

C G

D H J

Trees
Some typical operations upon a tree Insert Add a new node into a tree Delete Remove a node from a tree Search Find a node (if it exists) that contains a given key

Traverse Systematically examine (an operate on) all nodes in a tree


A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 8

Binary Trees
Binary trees A binary tree is a tree in which no node has more than two children A B D E G
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University

C F H
Page 9

Ordered Binary Trees

Ordered binary trees An ordered binary tree is a binary tree in which


left descendants < given node < right descendants Applied recursively throughout the tree structure

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 10

Ordered Binary Trees


The following binary tree is not ordered

A B

C
E G F H

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 11

Ordered Binary Trees


The following binary tree is ordered

D B

E
C F G H

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 12

Ordered Binary Trees


The following binary tree is also ordered

D C

F
E G H

A
B

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 13

Ordered Binary Trees


The following binary tree is also ordered

A B C D E

F
G H

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 14

Ordered Binary Trees


Ordered binary trees are often referred to as binary search trees (BST)
They tend to be a co-operative structure on which to work

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 15

Searching a BST
Searching a BST Algorithm Start with root node if search key = node key then stop else if search key < node key then go left else go right Stop if at any time during the search, you fall off the tree, stop

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 16

Searching a BST
Find node with key C

D B

E
C F G ` H

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 17

Searching a BST
Find node with key X

D B

E
C F G H

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 18

Searching a BST
Given an existing BST, searching for a key is simple Effectively a binary search Is it as efficient as a binary search? Algorithm is recursive, but can be trivially implemented iteratively Could be implemented as follows:

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 19

Searching a BST
bool Search(nodeptr curr, char key) { bool found; nodeptr curr; curr = root; found = false; while ((curr != NULL) && (! found)) if (curr->data == key) found = true; else if (key < curr->data) curr = curr->left; else curr = curr->right; return found; }

// We can also do the search recursively


A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 20

Traversing a Tree
Tree traversal is a common operation Traversal of a tree can be divided into two category: Depth-First Traversal and Breadth-First Traversal Three common types of depth-first traversal are: Pre-order, post-order, and in-order traversal Depth-First Traversal can be easily done recursively We can also use stack operation to print a traverse a tree Breath-First traversal can be done with Queue
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 21

Recursive Depth-First Traversal


In-order traversal Perform an In-order traversal of the left sub-tree Visit the current node Perform an In-order traversal of the right sub-tree Pre-order traversal Visit the current node Perform a pre-order traversal of the left sub-tree Perform a pre-order traversal of the right sub-tree

Post-order traversal Perform a Post-order traversal of the left sub-tree Perform a Post-order traversal of the right sub-tree Visit the current node
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 22

void InOrderTraversal (NodePtr root) { if (root = = NULL) return; InOrder(root->left); cout << root ->data << endl; InOrder(root->right); } void PreOrderTraversal (NodePtr root) { if (root = = NULL) return; cout << root ->data << endl; PreOrder(root->left); PreOrder(root->right); } void PostOrderTraversal (NodePtr root) { if (root = = NULL) return; PostOrder(root->left); PostOrder(root->right); cout << root ->data << endl; }

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 23

Depth-First Traversal with Stack


In Order - Traversal
void Tree::PrintInOrderTreeWithStack(TreeStructPtr Root) { Stack stk; TreeStructPtr p = Root; while (p!= NULL) { while (p != NULL) { if (p->Right != NULL) stk.push(p->Right); stk.push(p); p=p->Left; } p = stk.pop(); while (!stk.empty() && p->Right == NULL) { cout << p->Number << "-->"; p = stk.pop(); } cout << p->Number << "-->"; if (!stk.empty()) p = stk.pop(); else p = NULL; } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 24

Depth-First Traversal with Stack


Pre Order - Traversal
void Tree::PrintPreOrderTreeWithStack(TreeStructPtr Root) { Stack stk; TreeStructPtr p = Root; if (p != NULL) { stk.push(p); while (!stk.empty()) { p = stk.pop(); cout << p->Number << "-->"; if (p->Right != NULL) stk.push(p->Right); if (p->Left != NULL) stk.push(p->Left); } } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 25

Depth-First Traversal with Stack


Post Order - Traversal
void Tree::PrintPostOrderTreeWithStack(TreeStructPtr Root) { Stack stk; TreeStructPtr p = Root, q = Root; while (p!= NULL) { for ( ; p->Left != NULL; p = p->Left) stk.push(p); while (p != NULL && (p->Right == NULL || p->Right == q)) { cout << p->Number << "-->"; q = p; if (stk.empty()) return; p = stk.pop(); } stk.push(p); p = p->Right; } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 26

Breadth-First Traversal
D B A C E

G ` F
H

In Breadth-First traversal, all the nodes in the first level are printed, followed by the nodes in second level, followed by the nodes in the third level and so on.

For example, the breadth-first traversal of the above graph gives: D B E A C G F H


Queue can be used to implement the Breadth-first traversal
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 27

Breadth-First Traversal with Queue


void Tree::PrintBreadthFirstWithQueue(TreeStructPtr Root) { Queue que; TreeStructPtr p = Root; if (p != NULL) { que.push(p); while (!que.empty()) { p = que.pop(); cout << p->Number << "-->"; if (p ->Left != NULL) que.push(p->Left); if (p->Right != NULL) que.push(p->Right); } } }

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 28

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 29

MorrisInOrder() { P = Root while not finished if P has no left descendant { visit it; P = P->Right; } else { Temp = the right child of the rightmost node in its left descendant of P

Temp

Temp->Right = P;
P = Root } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 30

P 10 5 3 7 Temp 20 3

P 5 7 Temp 3 Temp

P 5 7 10 20

10

Step 1
P 3 Temp 5 7 10

Step 2

Step 3

20

Now we can print the linked list. The nodes are organized in in-order form like a singular linked list
20
National University Page 31

Step 4
A.R. Hadaegh Dr. Ahmad R. Hadaegh

Temp 5

P
7 10 3 Temp

3 Temp 10

7
P 10

Step 5
5 Temp

20

Step 6
Temp 10 5

20

Step 7
Temp 10 5 3 7

20

20 7

20

10

P 3 P=NULL

Step 8

20

Step 9

Step 10

Now the tree is back to its original shape after the traversal is done
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 32

Insertions
Binary trees are normally created by inserting nodes into an initially empty tree If tree empty, first insert will create the root node Otherwise, tack new node onto the (unique) appropriate node that has less than 2 children This will require a search routine

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 33

Insert 15, 8, 12, 19, 5, and 23 into an empty BST 15 8 Step 1 Step 2 Step 3 15 8 12 15

15
8 19 8 5 Step 5

15
19 12 5 Step 6
National University

15
8 19

12
Step 4
A.R. Hadaegh Dr. Ahmad R. Hadaegh

12

23

Page 34

// This procedure implements a recursive insert. // it can also be done iteratively. void insert (nodeptr& root, nodeptr newnode) { if (root == null) root = newnode; else if (newnode->data < root->data) insert (root->left, newnode); else insert (root->right, newnode); }

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 35

void Tree::InsertWithNoRecursion(TreeStructPtr& Root, int x) { TreeStructPtr p = Root, prev=Root; while (p != NULL) This is the implementation { prev = p; if (x < p->Number) of the insert function p = p->Left; without using Recursion else if (x > p->Number) p = p->Right; else { cout << "\n!!!! " << x << " is already in the tree " << endl; return; } } TreeStructPtr NewNode; NewNode = new (TreeStruct); NewNode->Number = x; NewNode->Left = NULL; NewNode->Right = NULL; if (Root = = NULL) Root = NewNode; else if (prev->Number < x) prev->Right = NewNode; else prev->Left = NewNode; return; }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 36

Deletions
Deleting is a little more difficult. Why? When deleting from a BST, the algorithm must often reorganize tree while maintaining the inherent ordering Three cases to consider

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 37

Case 1: Deleting a leaf node This is easy -- detach leaf node from tree by setting its parents pointer to nil For example, suppose we want to delete 12 15 8 5 12 19 23 15 ` 5 8 12 15 ` 19 23

8
5
A.R. Hadaegh Dr. Ahmad R. Hadaegh

19 23
National University Page 38

Case 2: Deleting a node with a single child Easy -- replace the node to be deleted with its child For example, suppose we want to delete 19 15 8 5 12 19 23 15 5 8 12 15 19 23

8
5
A.R. Hadaegh Dr. Ahmad R. Hadaegh

23 12
National University Page 39

Case 3: Deleting a node with two Children For example, suppose we want to delete 21

12 8 7 10 17 21 23

These nodes must be properly linked back into the tree

14

19

22

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 40

There are Two possible algorithms for delete Method 1: Replace the deleted node with one of its children, say the left child (i.e. node 17) The remaining right child (i.e. node 23) must now be linked back into the tree Place it on the right of the largest node of the new left subtree

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 41

Replace the deleted node with one of its children, say the left child (i.e. node 17)

12
8 7 10 21

17

23

14

19

22

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 42

12 8 7 10 17 23

14

19

22

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 43

Place it (node 23) on the right of the largest node of the new left subtree

12 8 7 10 17 23

14

19

22

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 44

Done!

12

8
7

17

10

14

19

23

22
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University

23
Page 45

Deletions
Method 2: Locate the in-order successor of the node to be deleted (the node that contains the next highest value) To locate the in-order successor, go right, then go left as far as possible

Replace the contents of the node to be deleted with the contents of its in-order successor
Delete the successor node This algorithm is possible since the in-order successor node will never have more than one child
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 46

Delete 21

12 8 7 10 17 21 23

14

19

22

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 47

Replace the contents of the node to be deleted with the contents of its in-order successor

12 8 7 10 17 21 23

14

19

22

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 48

Now swap the value of the node with the value of its successor node

12 8 7 10 17 22 23

14

19

21

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 49

Delete the successor node

12

8
7 10 17

22 23

14

19

21

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 50

Deletions
Done!

12 8 7 10 17 22 23

14

19

26

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 51

An alternative approach to the second method is to find predecessor of a node instead of the successor node. This mainly works the same as the second method Another issue to consider is that the second method does not change the structure of the tree as much as the first method does. The height of the tree does not change as much in the second method compare to the first method

However, if we keep applying the second method for deletion and choose successor node to replace with the node, the tree eventually becomes unbalanced
One way to improve the second method is we can write the algorithm to alternatively delete the predecessor of the node from the left subtree and delete the successor from the right subtree
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 52

Balancing a Binary Tree


A binary tree is height-balanced or simply balanced if the difference between the left subtree and right subtree of any node is either 0 or 1 For example, consider the following binary tree:
Node Height of the Height of the left subtree right subtree Difference

P K B

1 1 0

1 2 3

0 1 3

K
D P

Because there is at least one node (node B) with the difference value of 3, this tree is not balanced
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University

R
Page 53

Suppose we receive a set of data all in one shot and we want to insert them into a binary tree such that the end result is a balanced binary search tree. If we insert the data one by one randomly, the tree may not turn to be a balanced binary search tree. One method to solve this problem is to First sort the data using the best sort algorithm available Designate the middle element to be the root of the binary tree The array would consist of two sub arrays: one from the first element to the middle element (the root) but not including the middle element Another consists of middle + 1 till the last element Now the left child of the tree is taken from the middle of the first sub-array and its right child from the middle of the second sub-array Now divide the first sub-array into two other sub-arrays and repeat the same process Similarly divide the other sub-array into two other sub-arrays and repeat the same process
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 54

The algorithm is:

void Tree:: Balance (T data[ ], int first, int last) { if (first <=last) { int middle = (first + last) /2; insert (data[middle]); Balance (data, first, middle-1) Balance(data, middle+1, last); } }

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 55

Example: Stream of data: 5 1 9 8 7 0 2 3 4 6 Sorted Data: 0123456789

Step 1

0 1 2 3 4 5 6 7 8 9
4

Step 2

2 3

4 4

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 56

Step 3

2 3

4 4

1 0

Step 4

1 2 3 4 5 6 7 8 9
4

1
0
A.R. Hadaegh Dr. Ahmad R. Hadaegh

2
National University Page 57

Step 5

2 3

4
4

1 0

2
3

Step 6

1 2 3 4 5 6 7 8 9
4 1 0 2 3 7

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 58

Step 7

2 3

4
4

1 0 2 3 5

Step 8

2 3

4
4

1 0
2 5

3
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University

6
Page 59

Step 9

2 3

4
4

1 0 2 3 5

7 8 6

Step 10

2 3

4
4

1 0 2 3
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University

5
6

8
9
Page 60

What if we already have a balanced binary search tree and we want to insert another element such that after insertion the tree remains balanced One solution is to sort all elements including the new one again and then re-insert the elements again to the tree as we discussed before. Another solution proposed by C. Day and later improved by Q. Stout and B. Warren. Their solution is known as DSW algorithm DSW algorithm avoids sorting. It acquires deconstructing and reconstructing of the tree The building block for the tree transformation in this algorithm is the rotation

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 61

There are two types of rotations: Left rotation and Right Rotation which are symmetrical to one another The right rotation of a node called Child around its parent node called Parent is performed according to the following algorithm RotateRight (Grandparent, Parent, Child) { - If Parent is not the root of the tree Grandparent of child becomes childs parent by replacing the parent - Right subtree of child becomes left subtree of childs parent

- Node child acquire parent as its right child


}

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 62

The following is an example of right rotation


Gr Par Ch b c a
Right rotation of Ch around Par

Gr
Ch b c Par a

Gr Par a b
A.R. Hadaegh Dr. Ahmad R. Hadaegh

Gr
Left rotation of Ch around Par

Ch Par c b
Page 63

Ch c
National University

DSW algorithm transforms an arbitrary binary search tree into a linked list like tree called a backbone tree Then the backbone tree is transformed in a series of passes into a perfectly balanced tree by repeatedly rotating every second node of the backbone around its parent
5

5
10 20 15 25 23 28 30 40

25 10 15

20
23 25 28 30 40 5 10

20

30

23

28

40

15

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 64

In the first phase, the backbone is created using the following algorithm: createBackbone(root, n) { tmp = root; while (tmp != NULL) if tmp has a left child { rotate this child around tmp; set tmp to the child which just became parent } else set tmp to its right child

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 65

tmp 5 10 5 10 tmp 20 30 25 23 28 40 23 15 25 28 30

5 10 tmp

20
15

15 20
30 40

25
23 28

40

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 66

5
10 tmp 15 20 30 25 23 28 40

5 10 15 20

5 10 15

20 tmp
30

tmp 25

25
23 28

40

23

30

28

40

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 67

5 5 10 10 10 5

15
20

15
tmp 25 20 tmp 25

15 20 tmp 23 30

23

30

23
28 40

25
40

28

30
28 40

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 68

5 10
15 20 tmp 23 25 30 28 40 10 15 20 23

5 10 15 20 23 25

5
10 15 20 23

25
tmp 30 tmp 28 30

25 28 30

28

40

40

40 tmp=NULL

A.R. Hadaegh Dr. Ahmad R. Hadaegh

National University

Page 69

In the second phase, the Backbone is transformed into a tree but this time the tree is perfectly balanced by having leaves on two adjacent levels In each pass down the backbone, every second node down to a certain point is rotated around its parent The algorithm is as follows:

createPerfectTree(n) { m = 2 lg(n+1) -1 Make n m rotations starting from the top of the backbone while (m >1) { m = m/2 make m rotations starting from the top of the backbone } }
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 70

Step 1
5 10 10

Step 2
20

Step 3
10
25 23 30 28 m = 3/2 = 1 40

15
5 20 15 23 25

20
23 25 28

15

28
30 30 40 n=9 m=7 So we need to do nm=2 rotations
A.R. Hadaegh Dr. Ahmad R. Hadaegh

So we need to do one rotation m = 1/2 = 0 No more rotation is necessary 20 10 5 15


Page 71

Step 4
25 30

40 m = 7/2 = 3 So we need to do three rotations

23

28

40

National University

Can you do this example now.

1 2 4 3 7 6 8

9
10

Some of the code in this lecture is placed in example 1 for the tree lecture in the web
A.R. Hadaegh Dr. Ahmad R. Hadaegh National University Page 72

You might also like