Binary Tree Traversal Traversal of Binary Tree n
Binary Tree Traversal
Traversal of Binary Tree n Traversal n n Why the traversal necessary? n n n The process of visiting each node in a tree Checking whether insertions/deletions work well. Searching a specific node. How to visit all nodes once? A C B D H 2 E I G F J K
Traversal of Binary Tree n Traversal methods n Inorder traversal: LCR n n Preorder traversal: CLR n n Visiting the root node before subtrees Postorder traversal: LRC n n Visiting a left subtree, a root node, and a right subtree Visiting subtrees before visiting the root node Level order traversal C L 3 R
Inorder Traversal (LCR) n Algorithm: LCR n n n Step 1: Visiting a left subtree Step 2: Visiting the root node Step 3: Visiting a right subtree 6 2 C A 9 C 4 B 2 L 1 5 E D 7 11 G F R 3 1 H 4 I 3 8 J K 10
Inorder Traversal (LCR) Root A C B D H E G F I J K Right subtree Left subtree C B D H E A I G F J 5 K
Inorder Traversal (LCR) D B B H D H E E A I A Right subtree I H D I B E A Left subtree C C K J G F K Left subtree Right subtree F 6 J C K G
Inorder Traversal (LCR) n Algorithm void Inorder(BTree. Node* root) { if (root != NULL) { Inorder(root->left_child); printf("%d ", root->item); Inorder(root->right_child); } } 6 A 9 C 4 B 2 1 H 5 E D I 3 7 11 G F 8 J K 10 HDIBEAFJCKG 7
Preorder Traversal (CLR) n Algorithm: CLR n n n Step 1: Visiting the root node Step 2: Visiting a left subtree Step 3: Visiting a right subtree 1 1 C A 7 C 2 B 3 L 2 6 E D 8 10 G F R 3 4 H 8 I 5 9 J K 11
Preorder Traversal (CLR) Root A C B D H E G F I J K Right subtree Left subtree C B D A H E I 9 G F J K
Preorder Traversal (CLR) D B A B E H D A H I E Right subtree I A B D H I E Left subtree C F G C J G F J K K Left subtree Right subtree C 10 F J G K
Preorder Traversal (CLR) n Algorithm: CLR void Preorder(BTree. Node* root) { if (root != NULL) { printf("%d ", root->item); Preorder(root->left_child); Preorder(root->right_child); } } 3 4 H 1 A 7 C 2 B 6 E D I 5 8 10 G F 9 J ABDHIECFJGK 11
Postorder Traversal (LRC) n Algorithm: LRC n n n Step 1: Visiting a left subtree Step 2: Visiting a right subtree Step 3: Visiting the root node 11 3 C A 10 C 5 B 3 L 1 4 E D 7 9 G F R 2 1 H 12 I 2 6 J K 8
Postorder Traversal (LRC) Root A C B D H E I J C B H K Right subtree Left subtree D G F E G F I J 13 K A
Postorder Traversal (LRC) D B E H D H B I E Right subtree I H I D E B Left subtree G F C C G F J J A K Left subtree Right subtree J 14 A K F K G C A
Postorder Traversal (LRC) n Algorithm: LRC void Postorder(BTree. Node* root) { if (root != NULL) { Postorder(root->left_child); Postorder(root->right_child); printf("%d ", root->item); } } 3 1 H 11 A 10 C 5 B 4 E D I 2 7 9 G F 6 J K 8 HIDEBJFKGCA 15
Inorder 6 A 9 4 C B 5 2 D 1 Preorder 2 3 4 H 1 3 G F 8 J 10 K A 5 7 C E 5 I 11 11 B D I H E 7 6 8 G F 9 J 10 K 11 3 1 H 10 C B D E I Postorder A 2 4 7 G F 6 J 9 K 8
Level Order Traversal n Algorithm n For each level, visit nodes from the left to right direction. 1 Level 0 Level 3 3 C 2 Level 1 Level 2 A B 4 8 H 5 E D I 6 F 10 J 9 ABCDEFGHIJK 17 7 G K 11
Level Order Traversal n Algorithm n Traverse a tree by using a queue (FIFO) n When dequeuing a node, enqueue its children from the left to the right direction. 1 A 3 C 2 B 4 8 H 5 E D I 9 6 F 10 J 7 G K 11 18 En. Queue A A En. Queue B, C B C En. Queue D, E C D E En. Queue F, G D E F G En. Queue H, I E F G H En. Queue - F G H I En. Queue J G H I J En. Queue K H I J K I
Level Order Traversal void Levelorder(BTree. Node* root) { Queue queue; if (root == NULL) return; Init. Queue(&queue); En. Queue(&queue, root); while (!Is. Empty(&queue)) { root = Peek(&queue); De. Queue(&queue); printf("%d ", root->item); if (root->left_child != NULL) En. Queue(&queue, root->left_child); if (root->right_child != NULL) En. Queue(&queue, root->right_child); } } 19
Calculating Directory Size n How to accumulate directory size? n Each file has different size, and each directory has 10 K + 450 K 10 K + 200 K 50 K 10 K + 230 K 150 K 20 30 K
Calculating Directory Size // Make use of postorder traversal. int Cal. Directory. Size(BTree. Node *root) { int left_size, right_size; if (root == NULL) return 0; else { left_size = Cal. Directory. Size(root->left_child); right_size = Cal. Directory. Size(root->right_child); return (root->item + left_size + right_size); } } 10 10 10 50 150 200 21 30
Binary Expression Tree n Infix notation: X + Y n n n Operators are written in-between their operands. Need extra information to make the order of evaluation of the operators clear. Example: (7 + 4) * 2 – 1 n The expression tree is easier to understand than infix notation. * (7 + 4) * 2 - 1 + 22 7 1 2 4
Binary Expression Tree n Definition n Representing an expression as a tree. n Non-leaf node: operator, leaf node: operand + + a * b a - + c b a * b c a+b a*b+c a+b-c*d Infix a+b a*b+c a+b-c*d Prefix +ab +*abc -+ab*cd Postfix ab+ ab*c+ ab+cd*- 23 d
Calculating Expression Tree n Calculate 7 + 4 and update the node. * 1 * 2 + 11 7 1 4 Calculating 7 + 4 24 2
Calculating Expression Tree n Calculate 11 * 2 and update the node. * 1 22 1 2 11 Calculating 11 * 2 n Calculate 22 - 1 and update the node. 21 22 1 Calculating 22 - 1 25
Calculating Expression Tree int Calculate. Exp. Tree(BTree. Node * root) { int op 1, op 2; if (root == NULL) return 0; if (root->left_child == NULL && root->right_child == NULL) return root->item; op 1 = Calculate. Exp. Tree(root->left_child); op 2 = Calculate. Exp. Tree(root->right_child); switch (root->item) { case '+': return case '-': return case '*': return case '/': return } return 0; op 1 + * / op 2; } 26
Building Expression Tree n Overall procedure Infix notation Postfix notation (7 + 4) * 2 - 1 74+2*1 - Expression tree * n Infix notation postfix notation n + Use a stack (See Lecture Note 3). 7 n Postfix notation expression tree n Build a tree incrementally using a stack. 27 1 2 4
Building Expression Tree n Push nodes from operands until finding a operator. 7 4 + 2 * 1 4 7 n Pop two nodes and push an expression tree. + 7 4 + 2 * 1 T T 28 = 7 4
Building Expression Tree n Push nodes from operands until finding a operator. 7 4 + 2 * 1 - + 2 T = 7 T n 4 Pop two nodes and push an expression tree. * 7 4 + 2 * 1 T’ T’ 29 = + 7 2 4
Building Expression Tree n Push nodes from operands until finding a operator. * 7 4 + 2 * 1 - 1 T’ = T’ n + 7 2 4 - Pop two nodes and push an expression tree. 7 4 + 2 * 1 - T’ ’ = + T’ ’ 30 * 7 1 2 4
Building Expression Tree BTree. Node * Make. Exp. Tree(char* exp, int len) { Stack stack; BTree. Node * node, *right_node, *left_node; Init. Stack(&stack); for (int i = 0; i < len; i++) { if ('0' <= exp[i] && exp[i] <= '9') node = Create. Node(exp[i]); else { right_node = Peek(&stack), Pop(&stack); left_node = Peek(&stack), Pop(&stack); node = Create. Node(exp[i]); Create. Right. Subtree(node, right_node); Create. Left. Subtree(node, left_node); } Push(&stack, node); } return Peek(&stack); } 31
Threaded Binary Tree n Variation of binary tree n Modify a binary tree to cheaply find its inorder successor. n n Have special threading links (dashed arrows). It can be fast traversal. A C B D H E G F I J 32 K
Threaded Binary Tree n Inorder traversal n Traverse a tree until finding the leftmost node. n n Solid arrows mean left-side movements. Traverse a tree by a threaded link or a right-side child pointer. n Dashed arrows mean right-side movements. 6 A 9 4 C B 2 1 H 5 D 7 E I 11 G F 3 8 33 J K 10
Node in Threaded Binary Tree n Node representation in threaded binary tree n If no right child node exists, the right_child pointer of the node refers to its inorder successor. n This node indicates a threaded node. typedef int BData; typedef struct _b. Tree. Node { BData item; struct _b. Tree. Node * left_child; struct _b. Tree. Node * right_child; bool is. Theaded; } BTree. Node; 34 item left_child right_child
Inorder in Threaded Binary Tree BTree. Node* left. Most(BTree. Node* node) { if (node == NULL) return NULL; while (node->left_child != NULL) node = node->left_child; // Go to the leftmost node. return node; } void inorder(BTree. Node* node) { BTree. Node* cur = leftmost(node); while (cur != NULL) { printf("%d ", cur->item); // If the node is a thread node, go to its inorder successor. if (cur->is. Theaded) cur = cur->right_child; else // Go to the leftmost child in a right subtree. cur = leftmost(cur->right_child); } } 35
- Slides: 35