CSEN 301 – Data Structures and Algorithms Lecture 11: Introduction to Trees Prof. Dr. Slim Abdennadher
[email protected] German University Cairo, Department of Media Engineering and Technology
22.11.2014 – 27.11.2014
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
1 / 21
Synopsis
Trees and recursion
Synopsis
Test your understanding We introduced Trees and binary Trees. What are the advantages/disadvantages of Trees over (linked) Lists or Arrays? Trees have a flexible size. Trees allow logarithmic insertion/deletion Trees allow logarithmic search
How does the topology of a tree affect the complexity? Trees have to be balanced to allow for the logarithmic access/search The actual topology depends on the order of insertion/deletion
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
2 / 21
Synopsis
Trees and recursion
Synopsis
Self similarity and recursion The structure of a tree is self-similar A subtree has the same properties as a tree. The structure is ideal for recursive approaches.
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
3 / 21
Synopsis
Keeping the balance
Problems with binary search trees
A balanced Tree is one that exhibits a good ratio of breadth to depth Binary Search Trees can become easily unbalanced. There are a special class of binary search trees that are self-balancing (i. e., as new nodes are added or existing nodes are deleted, these binary search trees automatically adjust their topology to maintain an optimal balance). Java SDK has a binary search tree class, TreeMap. This class uses one of the intelligent, self-balancing binary search tree derivatives, the red-black tree.
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
4 / 21
Trees – continued
Perils of deletion
Deleting a node
Deleting a node is more difficult than inserting! The hole created by the deletion needs to be filled. The node to fill the hole has to be chosen with care for keeping the search tree property
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
5 / 21
Trees – continued
Perils of deletion
Deleting a node Example (1) Delete node 50 Since 50 has no right child, we can simply replace it with 20 90
50
150
20
5
25 90
50 Abdennadher (GUC–MET)
150 CSEN 301
22.11.2014 – 27.11.2014
6 / 21
Trees – continued
Perils of deletion
Deleting a node Example (2) Delete node 150 Since 150’s right child has no right child, we can simply replace it with its right child 90
50
150
125
20
5
175
140
25 90
Abdennadher (GUC–MET)
50
CSEN 301
150
22.11.2014 – 27.11.2014
7 / 21
Trees – continued
Perils of deletion
Deleting a node Example (3) Delete node 50 Since 50’s right child contains a left child, we need to find the left-most descendant of 50’s right child. 90
50
150
20
5
75
25
66
80
68 90 Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
8 / 21
Trees – continued
Perils of deletion
Deleting a node: Three cases
Summary: Case 1: If the node being deleted is a leaf Simply change the appropriate child field in the node’s parent to point to null Case 2: If the node being deleted has one child Connect its parent directly to its child Case 3: If the node being deleted has two children then the deleted node needs to be replaced by the deleted node’s right child’s left-most descendant (i. e., the node with the smallest value in the right subtree)
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
9 / 21
Trees – continued
Deleting a node – implementation
Deleting a node: Implementation
Head and local variables public Node delete (Comparable key) { if (root == null) return null; Node current = root; Node parent = root; Node substitute = null; boolean isRight = true;
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
10 / 21
Trees – continued
Deleting a node – implementation
Deleting a node: Implementation Locating the node to be deleted while (current.data.compareTo (key) !=0) { if (current.data.compareTo (key) > 0) { isRight = false; parent = current; current = current.left; } else { isRight = true; parent = current; current = current.right; } if (current == null) return null; }
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
11 / 21
Trees – continued
Deleting a node – implementation
Deleting a node: Implementation
Cases 1 and 2 // Case 1: node has no children if (current.left == null && current.right == null) substitute = null; // Case 2: node has only one child else if (current.left == null) substitute = current.right; else if (current.right == null) substitute = current.left;
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
12 / 21
Trees – continued
Deleting a node – implementation
Deleting a node: Implementation Case 3 – finding and preparing the substitute // Case 3: node has two children else { Node successor = current.right; Node successorParent = current; while (successor.left != null) { successorParent = successor; successor = successor.left; } substitute = successor; if (successorParent != current) { successorParent.left = successor.right; substitute.right = current.right; } substitute.left = current.left; }
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
13 / 21
Trees – continued
Deleting a node – implementation
Deleting a node: Implementation
Cases done – replacing the node if (current == root) root = substitute; else if (isRight) parent.right = substitute; else parent.left = substitute; return current; }
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
14 / 21
Traversal
Ways through the tree
Traversing a Tree
Three different kinds of traversals: Preorder traversal Inorder traversal Postorder traversal
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
15 / 21
Traversal
Preorder
Traversing a Tree: Preorder traversal Tree representing an expression
×
×
13
50
+
94
70
Preorder traversal: × × 13 50 + 94 70 Preorder traversal: starts by visiting the current node, call it c, then its left child, and then its right child. Starting with the root as c, the sequence for a preorder method is: 1 2 3
Visit c. Call itself to traverse c’s left subtree. Call itself to traverse c’s right subtree.
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
16 / 21
Traversal
Preorder
Preorder traversal: Java code
Preorder public String TraversePreAll () { return TraversePre (root); } public String TraversePre (Node current) { if (current == null) return ""; else return current.data + " " + TraversePre (current.left) + TraversePre (current.right); }
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
17 / 21
Traversal
Postorder
Traversing a Tree: Postorder traversal Tree representing an expression
×
×
13
50
+
94
70
Postorder traversal: 13 50 × 94 70 + × Postorder traversal: starts by visiting the current node’s left child, then its right child, and finally the current node. Starting with the root as c, the sequence for a preorder method is: 1 2 3
Call itself to traverse c’s left subtree. Call itself to traverse c’s right subtree. Visit c.
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
18 / 21
Traversal
Postorder
Postorder traversal: Java code
Postorder public String TraversePostAll () { return TraversePost (root); } public String TraversePost (Node current) { if(current == null) return ""; else return TraversePost(current.left) + TraversePost(current.right) + current.data + " "; }
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
19 / 21
Traversal
Inorder
Traversing a Tree: Inorder traversal Tree representing an expression
×
×
13
50
+
94
70
Inorder traversal: 13 × 50 × 94 + 70 Inorder traversal: starts by visiting the current node’s left child, then the node itself, then its right child. Starting with the root as c, the sequence for a preorder method is: 1 2 3
Call itself to traverse c’s left subtree. Visit c. Call itself to traverse c’s right subtree.
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
20 / 21
Traversal
Inorder
Inorder traversal: Java code
Inorder public String TraverseInAll () { return TraverseIn (root); } public String TraverseIn (Node current) { if(current == null) return ""; else return TraverseIn (current.left) + current.data + " " + TraverseIn(current.right); }
Abdennadher (GUC–MET)
CSEN 301
22.11.2014 – 27.11.2014
21 / 21