Tree Traversal Techniques Heaps Tree Traversal Concept Tree

  • Slides: 34
Download presentation
Tree Traversal Techniques; Heaps • Tree Traversal Concept • Tree Traversal Techniques: Preorder, Inorder,

Tree Traversal Techniques; Heaps • Tree Traversal Concept • Tree Traversal Techniques: Preorder, Inorder, Postorder • Full Trees • Almost Complete Trees • Heaps CS 103 1

Binary-Tree Related Definitions • The children of any node in a binary tree are

Binary-Tree Related Definitions • The children of any node in a binary tree are ordered into a left child and a right child 1 • A node can have a left and 3 a right child, a left child only, a right child only, 5 8 or no children 4 6 • The tree made up of a left child (of a node x) and all its 11 descendents is called the left subtree of x • Right subtrees are defined similarly CS 103 7 9 10 12 2

A Binary-tree Node Class class Tree. Node { public: typedef int datatype; Tree. Node(datatype

A Binary-tree Node Class class Tree. Node { public: typedef int datatype; Tree. Node(datatype x=0, Tree. Node *left=NULL, Tree. Node *right=NULL){ data=x; this->left=left; this->right=right; }; datatype get. Data( ) {return data; }; Tree. Node *get. Left( ) {return left; }; Tree. Node *get. Right( ) {return right; }; void set. Data(datatype x) {data=x; }; void set. Left(Tree. Node *ptr) {left=ptr; }; void set. Right(Tree. Node *ptr) {right=ptr; }; private: datatype data; // different data type for other apps Tree. Node *left; // the pointer to left child Tree. Node *right; // the pointer to right child }; CS 103 3

Binary Tree Class class Tree { public: typedef int datatype; Tree(Tree. Node *root. Ptr=NULL){this->root.

Binary Tree Class class Tree { public: typedef int datatype; Tree(Tree. Node *root. Ptr=NULL){this->root. Ptr=root. Ptr; }; Tree. Node *search(datatype x); bool insert(datatype x); Tree. Node * remove(datatype x); Tree. Node *get. Root(){return root. Ptr; }; Tree *get. Left. Subtree(); Tree *get. Right. Subtree(); bool is. Empty(){return root. Ptr == NULL; }; private: Tree. Node *root. Ptr; }; CS 103 4

Binary Tree Traversal • Traversal is the process of visiting every node once •

Binary Tree Traversal • Traversal is the process of visiting every node once • Visiting a node entails doing some processing at that node, but when describing a traversal strategy, we need not concern ourselves with what that processing is CS 103 5

Binary Tree Traversal Techniques • Three recursive techniques for binary tree traversal • In

Binary Tree Traversal Techniques • Three recursive techniques for binary tree traversal • In each technique, the left subtree is traversed recursively, the right subtree is traversed recursively, and the root is visited • What distinguishes the techniques from one another is the order of those 3 tasks CS 103 6

Preoder, Inorder, Postorder • In Preorder, the root is visited before (pre) the subtrees

Preoder, Inorder, Postorder • In Preorder, the root is visited before (pre) the subtrees traversals • In Inorder, the root is visited in-between left and right subtree traversal • In Preorder, the root is visited after (pre) the subtrees traversals Preorder Traversal: 1. Visit the root 2. Traverse left subtree 3. Traverse right subtree CS 103 7 Inorder Traversal: 1. Traverse left subtree 2. Visit the root 3. Traverse right subtree Postorder Traversal: 1. Traverse left subtree 2. Traverse right subtree 3. Visit the root

Illustrations for Traversals • Assume: visiting a node is printing its label • Preorder:

Illustrations for Traversals • Assume: visiting a node is printing its label • Preorder: 1 3 5 4 6 7 8 9 10 11 12 4 • Inorder: 4 5 6 3 1 8 7 9 11 10 12 • Postorder: 4 6 5 3 8 11 12 10 9 7 1 CS 103 1 3 7 5 8 9 10 6 11 12 8

Illustrations for Traversals (Contd. ) • Assume: visiting a node is printing its data

Illustrations for Traversals (Contd. ) • Assume: visiting a node is printing its data • Preorder: 15 8 2 6 3 7 11 10 12 14 20 27 22 30 • Inorder: 2 3 6 7 8 10 11 12 14 15 20 22 27 30 • Postorder: 3 7 6 2 10 14 12 11 8 22 30 27 20 15 CS 103 15 20 8 6 10 12 3 27 11 2 7 22 30 14 9

Code for the Traversal Techniques • The code for visit is up to you

Code for the Traversal Techniques • The code for visit is up to you to provide, depending on the application • A typical example for visit(…) is to print out the data part of its input node void pre. Order(Tree *tree){ if (tree->is. Empty( )) return; visit(tree->get. Root( )); pre. Order(tree->get. Left. Subtree()); pre. Order(tree->get. Right. Subtree()); } void in. Order(Tree *tree){ if (tree->is. Empty( )) return; in. Order(tree->get. Left. Subtree( )); visit(tree->get. Root( )); in. Order(tree->get. Right. Subtree( )); } void post. Order(Tree *tree){ if (tree->is. Empty( )) return; post. Order(tree->get. Left. Subtree( )); post. Order(tree->get. Right. Subtree( )); visit(tree->get. Root( )); } CS 103 10

Application of Traversal Sorting a BST • • Observe the output of the inorder

Application of Traversal Sorting a BST • • Observe the output of the inorder traversal of the BST example two slides earlier It is sorted This is no coincidence As a general rule, if you output the keys (data) of the nodes of a BST using inorder traversal, the data comes out sorted in increasing order CS 103 11

Other Kinds of Binary Trees (Full Binary Trees) • Full Binary Tree: A full

Other Kinds of Binary Trees (Full Binary Trees) • Full Binary Tree: A full binary tree is a binary tree where all the leaves are on the same level and every non-leaf has two children • The first four full binary trees are: CS 103 12

Examples of Non-Full Binary Trees • These trees are NOT full binary trees: (do

Examples of Non-Full Binary Trees • These trees are NOT full binary trees: (do you know why? ) CS 103 13

Canonical Labeling of Full Binary Trees • Label the nodes from 1 to n

Canonical Labeling of Full Binary Trees • Label the nodes from 1 to n from the top to the bottom, left to right 1 1 1 3 2 4 1 2 4 5 6 3 2 3 7 8 9 10 111213 14 15 5 6 7 Relationships between labels of children and parent: i 2 i+1 2 i CS 103 14

Other Kinds of Binary Trees (Almost Complete Binary trees) • Almost Complete Binary Tree:

Other Kinds of Binary Trees (Almost Complete Binary trees) • Almost Complete Binary Tree: An almost complete binary tree of n nodes, for any arbitrary nonnegative integer n, is the binary tree made up of the first n nodes of a canonically labeled full binary 1 1 2 4 1 2 2 3 4 7 4 CS 103 2 1 2 3 5 6 1 1 3 4 3 5 6 5 15

Depth/Height of Full Trees and Almost Complete Trees • The height (or depth )

Depth/Height of Full Trees and Almost Complete Trees • The height (or depth ) h of such trees is O(log n) • Proof: In the case of full trees, – The number of nodes n is: n=1+2+22+23+…+2 h=2 h+1 -1 – Therefore, 2 h+1 = n+1, and thus, h=log(n+1)-1 – Hence, h=O(log n) • For almost complete trees, the proof is left as an exercise. CS 103 16

Canonical Labeling of Almost Complete Binary Trees • Same labeling inherited from full binary

Canonical Labeling of Almost Complete Binary Trees • Same labeling inherited from full binary trees • Same relationship holding between the labels of children and parents: Relationships between labels of children and parent: i 2 i+1 2 i CS 103 17

Array Representation of Full Trees and Almost Complete Trees • A canonically label-able tree,

Array Representation of Full Trees and Almost Complete Trees • A canonically label-able tree, like full binary trees and almost complete binary trees, can be represented by an array A of the same length as the number of nodes • A[k] is identified with node of label k • That is, A[k] holds the data of node k • Advantage: – no need to store left and right pointers in the nodes save memory – Direct access to nodes: to get to node k, access A[k] CS 103 18

Illustration of Array Representation 15 20 8 2 13 15 1 8 20 2

Illustration of Array Representation 15 20 8 2 13 15 1 8 20 2 2 3 4 30 11 6 18 27 12 11 30 27 13 6 10 12 5 6 7 8 9 10 11 • Notice: Left child of A[5] (of data 11) is A[2*5]=A[10] (of data 18), and its right child is A[2*5+1]=A[11] (of data 12). • Parent of A[4] is A[4/2]=A[2], and parent of A[5]=A[5/2]=A[2] CS 103 19

Adjustment of Indexes • Notice that in the previous slides, the node labels start

Adjustment of Indexes • Notice that in the previous slides, the node labels start from 1, and so would the corresponding arrays • But in C/C++, array indices start from 0 • The best way to handle the mismatch is to adjust the canonical labeling of full and almost complete trees. • Start the node labeling from 0 (rather than 1). • The children of node k are now nodes (2 k+1) and (2 k+2), and the parent of node k is (k-1)/2, integer division. CS 103 20

Application of Almost Complete Binary Trees: Heaps • A heap (or min-heap to be

Application of Almost Complete Binary Trees: Heaps • A heap (or min-heap to be precise) is an almost complete binary tree where – Every node holds a data value (or key) – The key of every node is ≤ the keys of the children Note: A max-heap has the same definition except that the Key of every node is >= the keys of the children CS 103 21

Example of a Min-heap 5 20 8 15 33 16 18 30 11 27

Example of a Min-heap 5 20 8 15 33 16 18 30 11 27 12 CS 103 22

Operations on Heaps • Delete the minimum value and return it. This operation is

Operations on Heaps • Delete the minimum value and return it. This operation is called delete. Min. • Insert a new data value Applications of Heaps: • A heap implements a priority queue, which is a queue that orders entities not a on first-come first-serve basis, but on a priority basis: the item of highest priority is at the head, and the item of the lowest priority is at the tail • Another application: sorting, which will be seen later CS 103 23

Delete. Min in Min-heaps • The minimum value in a min-heap is at the

Delete. Min in Min-heaps • The minimum value in a min-heap is at the root! • To delete the min, you can’t just remove the data value of the root, because every node must hold a key • Instead, take the last node from the heap, move its key to the root, and delete that last node • But now, the tree is no longer a heap (still almost complete, but the root key value may no longer be ≤ the keys of its children CS 103 24

Illustration of First Stage of deletemin 5 15 33 15 30 27 11 20

Illustration of First Stage of deletemin 5 15 33 15 30 27 11 20 8 16 18 12 16 18 33 30 11 12 12 15 33 12 20 8 11 30 27 20 8 27 16 18 15 33 CS 103 11 30 27 16 18 25

Restore Heap • To bring the structure back to its “heapness”, we restore the

Restore Heap • To bring the structure back to its “heapness”, we restore the heap • Swap the new root key with the smaller child. • Now the potential bug is at the one level down. If it is not already ≤ the keys of its children, swap it with its smaller child • Keep repeating the last step until the “bug” key becomes ≤ its children, or the it becomes a leaf CS 103 26

Illustration of Restore-Heap 12 20 8 15 33 8 11 30 20 12 27

Illustration of Restore-Heap 12 20 8 15 33 8 11 30 20 12 27 16 18 15 33 11 30 27 16 18 8 20 11 15 33 16 18 12 30 27 Now it is a correct heap CS 103 27

Time complexity of insert and deletmin • Both operations takes time proportional to the

Time complexity of insert and deletmin • Both operations takes time proportional to the height of the tree – When restoring the heap, the bug moves from level to level until, in the worst case, it becomes a leaf (in deletemin) or the root (in insert) – Each move to a new level takes constant time – Therefore, the time is proportional to the number of levels, which is the height of the tree. • But the height is O(log n) • Therefore, both insert and deletemin take O(log n) time, which is very fast. CS 103 28

Inserting into a minheap • Suppose you want to insert a new value x

Inserting into a minheap • Suppose you want to insert a new value x into the heap • Create a new node at the “end” of the heap (or put x at the end of the array) • If x is >= its parent, done • Otherwise, we have to restore the heap: – Repeatedly swap x with its parent until either x reaches the root of x becomes >= its parent CS 103 29

Illustration of Insertion Into the Heap • In class CS 103 30

Illustration of Insertion Into the Heap • In class CS 103 30

The Min-heap Class in C++ class Minheap{ //the heap is implemented with a dynamic

The Min-heap Class in C++ class Minheap{ //the heap is implemented with a dynamic array public: typedef int datatype; Minheap(int cap = 10){capacity=cap; length=0; ptr = new datatype[cap]; }; datatype delete. Min( ); void insert(datatype x); bool is. Empty( ) {return length==0; }; int size( ) {return length; }; private: datatype *ptr; // points to the array int capacity; int length; void double. Capacity(); //doubles the capacity when needed }; CS 103 31

Code for deletemin Minheap: : datatype Minheap: : delete. Min( ){ assert(length>0); datatype return.

Code for deletemin Minheap: : datatype Minheap: : delete. Min( ){ assert(length>0); datatype return. Value = ptr[0]; length--; ptr[0]=ptr[length]; // move last value to root element i=0; while ((2*i+1<length && ptr[i]>ptr[2*i+1]) || (2*i+2<length && (ptr[i]>ptr[2*i+1] || ptr[i]>ptr[2*i+2]))){ // “bug” still > at least one child if (ptr[2*i+1] <= ptr[2*i+2]){ // left child is the smaller child datatype tmp= ptr[i]; ptr[i]=ptr[2*i+1]; ptr[2*i+1]=tmp; //swap i=2*i+1; } else{ // right child if the smaller child. Swap bug with right child. datatype tmp= ptr[i]; ptr[i]=ptr[2*i+2]; ptr[2*i+2]=tmp; // swap i=2*i+2; } } return. Value; }; CS 103 32

Code for Insert void Minheap: : insert(datatype x){ if (length==capacity) double. Capacity(); ptr[length]=x; int

Code for Insert void Minheap: : insert(datatype x){ if (length==capacity) double. Capacity(); ptr[length]=x; int i=length; length++; while (i>0 && ptr[i] < ptr[i/2]){ datatype tmp= ptr[i]; ptr[i]=ptr[(i-1)/2]; ptr[(i-1)/2]=tmp; i=(i-1)/2; } }; CS 103 33

Code for double. Capacity void Minheap: : double. Capacity(){ capacity = 2*capacity; datatype *newptr

Code for double. Capacity void Minheap: : double. Capacity(){ capacity = 2*capacity; datatype *newptr = new datatype[capacity]; for (int i=0; i<length; i++) newptr[i]=ptr[i]; delete [] ptr; ptr = newptr; }; CS 103 34