Trees part 2 CSE 2320 Algorithms and Data

  • Slides: 14
Download presentation
Trees (part 2) CSE 2320 – Algorithms and Data Structures University of Texas at

Trees (part 2) CSE 2320 – Algorithms and Data Structures University of Texas at Arlington 12/16/2021 1

Student Self-Review • Review theoretical lecture on trees that was covered earlier in the

Student Self-Review • Review theoretical lecture on trees that was covered earlier in the semester. • Review your notes and materials on implementing trees in C. 2

Traversing a Binary Tree • Traversing is the process of going through each node

Traversing a Binary Tree • Traversing is the process of going through each node of a tree, and doing something with that node. Examples: – We can print the contents of the node. – We can change the contents of the node. – We can otherwise use the contents of the node in computing something. • There are four standard choices for the order in which we visit nodes when we traverse a binary tree. – Preorder (Root, L, R): we visit the node, then its left subtree, then its right subtree. (depth-first order) – Inorder (L, Root, R): we visit the left subtree, then the node, then the right subtree. (depth-first order) – Postorder (L, R, Root): we visit the left subtree, then the right subtree, then the node. (depth-first order) – Level order: all the nodes on the level going from 0 to the last level. (breadth-first) 3

inorder 1 12 preorder 1 5 0 1 12 6 Note: This is NOT

inorder 1 12 preorder 1 5 0 1 12 6 Note: This is NOT a search tree. It has no order relation between nodes. 7 3 2 10 4 8 Preorder (___, ___): _____________ 0 2 10 4 0 postorder 7 3 12 5 Inorder (___, ___): ____________ 0 0 1 8 12 0 1 5 12 6 7 3 2 10 4 Postorder (___, ___): ____________ 8 4

Recursive Tree Traversal void traverse_preorder(node. PT h){ if (h == NULL) return; do_something_with(h); traverse_preorder

Recursive Tree Traversal void traverse_preorder(node. PT h){ if (h == NULL) return; do_something_with(h); traverse_preorder (h->left); traverse_preorder (h->right); } void traverse_inorder(node. PT h){ if (h == NULL) return; traverse_inorder (h->left); do_something_with(h); traverse_inorder (h->right); } void traverse_postorder(node. PT h){ if (h == NULL) return; traverse_postorder(h->left); traverse_postorder(h->right); do_something_with(h); } typedef struct node * node. PT; struct node { int item; node. PT left; node. PT right; }; Other possible fields: - node. PT parent; - int size; //size of subtree rooted at this node. Useful for balancing trees. - Anything else you need to add to solve a problem For a tree with N nodes: Time complexity: Space complexity: 5

Class Practice • Write the following (recursive or not) functions, in class: – –

Class Practice • Write the following (recursive or not) functions, in class: – – Count the number of nodes in a tree Compute the height of a tree Level-order traversal – discuss/implement Print the tree in a tree-like shape – discuss/implement • Which functions are “similar” to the traversals discussed previously and to each other? 6

Recursive Examples Count the number of nodes in the tree Compute the height of

Recursive Examples Count the number of nodes in the tree Compute the height of the tree int count(node. PT h){ if (h == NULL) return 0; int c 1 = count(h->left); int c 2 = count(h->right); return c 1 + c 2 + 1; } int height(node. PT h){ if (h == NULL) return -1; int u = height(h->left); int v = height(h->right); if (u > v) return u+1; else return v+1; } c 1 c 2 u Can you write the count. Two used below? v It does not return the count, but modifies the argument ct. int ct = 0; count. Two(root, &ct); Printf("ct=%d", ct); // gives correct count 7

Recursive Examples: print tree Prints the contents of each node (assuming that the items

Recursive Examples: print tree Prints the contents of each node (assuming that the items in the nodes are characters) How will the output look like? What type of tree traversal is this? Note how the depth variable works: the correct depth is passed for each node, and even after the recursive call(s), it remains correct for the current node. E. g. after the call show(x->left, depth+1) depth is still the depth of this node. You should NOT change this code and pass depth by reference. void printnode(char c, int depth) { int i; for (i = 0; i < depth ; i++) printf(" "); printf("%cn", c); } void show(node. PT x, int depth) { if (x == NULL) { printnode("*", depth); return; } printnode(x->item, h); show(x->left, depth+1); show(x->right, depth+1); } Interview problem (From Daily Coding Problem) Return all paths from the root to leaves. Store one path? Store all paths? Time & Space complexity? Easier: Print all paths from the root to leaves. 8

Level-Order Traversal // Adapted from Sedgewick void traverse(node. PT h) { Queue Q =

Level-Order Traversal // Adapted from Sedgewick void traverse(node. PT h) { Queue Q = new_Queue(); put(Q, h); while (!empty(Q)) { h = get(Q); //gets first node print. Item(h->item); if (h->left != NULL) put(Q, h->left); if (h->right != NULL) put(Q, h->right); } } 0 1 5 12 6 7 3 2 10 4 8 Queue: ________________ Print: _________________ // Adapted from Sedgewick // Same code, but uses a function argument void traverse(node. PT h, void (*visit)(node. PT)) { Queue Q = new_Queue(); put(Q, h); while (!empty(Q)) { h = get(Q); //gets first node (*visit)(h); if (h->left != NULL) put(Q, h->left); if (h->right != NULL) put(Q, h->right); } } 9

// Visit function is an argument to traversal void trav. Gen(node. PT h, void

// Visit function is an argument to traversal void trav. Gen(node. PT h, void (*visit)(node. PT)) { if (h == NULL) return; (*visit)(h); trav. Gen (h->left, visit); trav. Gen (h->right, visit); } void traverse(node. PT h) { // recursive if (h == NULL) return; print. Node(h); traverse(h->left, visit); traverse(h->right, visit); } ----void traverse(node. PT h) { // iterative Stack S = new. Stack(max); push(S, h); while (!is. Empty(S)) { h = pop(S); print. Node(h); if (h->right!= NULL) push(S, h->right); if (h->left != NULL) push(S, h->left); } } Stack: Print: EXTRA – Recursive and Iterative Preorder Traversal (Sedgewick) 0 1 5 12 6 7 3 2 10 4 8 10

General Trees • In a general tree, a node can have any number of

General Trees • In a general tree, a node can have any number of children. • Left-child - right-sibling implementation – Draw tree and show example – (There is a one-to-one correspondence between ordered trees and binary trees) 11

Perfect Binary Trees In the other direction: number of nodes = 2 height+1 -1

Perfect Binary Trees In the other direction: number of nodes = 2 height+1 -1 A perfect binary tree with N nodes has: • +1 levels • Height : • leaves (half the nodes are on the last level) Level Nodes per • internal nodes (half the nodes are internal) level 1 2 4 3 6 5 7 . . . Sum of nodes from root up to this level 0 20 (=1) 21 – 1 (=1) 1 21 (=2) 22 – 1 (=3) 2 22 (=4) 23 – 1 (=7) … … i 2 i … … n 2 n 2 i+1 – 1 2 n+1 – 1 12

Properties of Full Trees • A full binary tree (0/2 children) with N internal

Properties of Full Trees • A full binary tree (0/2 children) with N internal nodes has: – N+1 external nodes. – 2 N edges (links). – height at least lg N and at most N: • lg N if all external nodes are at the same level (perfect tree) • N if each internal node has one external child. 13

Recursive Tree Traversal - Answer void traverse_preorder(node. PT h){ if (h == NULL) return;

Recursive Tree Traversal - Answer void traverse_preorder(node. PT h){ if (h == NULL) return; do_something_with(h); traverse_preorder (h->left); traverse_preorder (h->right); } void traverse_inorder(node. PT h){ if (h == NULL) return; traverse_inorder (h->left); do_something_with(h); traverse_inorder (h->right); } void traverse_postorder(node. PT h){ if (h == NULL) return; traverse_postorder(h->left); traverse_postorder(h->right); do_something_with(h); } typedef struct node * node. PT; struct node { int item; node. PT left; node. PT right; }; Other possible fields: - node. PT parent; - int size; //size of subtree rooted at this node. Useful for balancing trees. - Anything else you need to add to solve a problem For a tree with N nodes: Time complexity: Θ(N) Space complexity: Θ(tree. Height) (if we exclude the stack: Θ(1) ) 14