Chapter 6 - Tree
Chapter 6 - Tree
1
2
3
4
5
6
7
8
9
10
11
Expression Trees
12
Binary Tree ADT
DEFINITION: A binary tree ADT is either empty, or it consists
of a node called root together with two binary trees called
the left and the right subtree of the root.
Basic operations:
• Construct a tree, leaving it empty.
• Insert an element.
• Remove an element.
• Search an element.
• Retrieve an element.
• Traverse the tree, performing a given operation on each
13
element.
Binary Tree ADT
Extended operations:
• Determine whether the tree is empty or not.
• Find the size of the tree.
• Clear the tree to make it empty.
14
Specifications for Binary Tree
<void> Create()
<boolean> isFull()
<boolean> isEmpty()
<integer> Size()
<void> Clear()
<ErrorCode> Search (ref DataOut <DataType>)
Depend on various
<ErrorCode> Insert (val DataIn <DataType>) types of binary
<ErrorCode> Remove (val key <KeyType>) trees
(BST, AVL, 2d-tree)
<ErrorCode> Retrieve (ref DataOut <DataType>)
15
Specifications for Binary Tree
• Binary Tree Traversal: Each node is processed once and
only once in a predetermined sequence.
• Depth-First Traverse:
<void> preOrderTraverse (ref<void>Operation(ref Data <DataType>))
<void> inOrderTraverse (ref<void>Operation(ref Data <DataType>))
<void> postOrderTraverse (ref<void>Operation(ref Data <DataType>))
• Breadth-First Traverse:
<void> BreadthFirstTraverse (ref<void>Operation(ref Data <DataType>))
16
17
18
19
20
21
22
23
Contiguous Implementation of Binary Tree
BinaryTree
Data <Array of <DataType> >
End BinaryTree
0 1 2 3 4 5 6
A B C D E F G ...
Physical Conceptual
i
(suitable for complete tree,
nearly complete tree, and 2i+1 2i+2
bushy tree)
24
Contiguous Implementation of Binary Tree
Record
Data <DataType>
Parent <DataType>
Flag <ChildType>
End Record
BinaryTree
Data <Array of <Record> >
End BinaryTree
0 1 2 3 4 5 6 H
Data A B E C F G H ...
...
Conceptual
Parent - A B A C C F
Flag - L R R L R R ...
0 1 2 3 4 5 6
NLR A B E C F H G
LNR B E A F H C G H
Physical Conceptual
(A binary tree without identical data can be restored from
two array of LNR and NLR traverse) 26
Linked Implementation of Binary Tree
BinaryNode
A
data <DataType>
left <pointer>
right <pointer>
End BinaryNode B C
BinaryTree
root <pointer> E F G
End BinaryTree
Physical 27
Depth-First Traversal
Auxiliary functions for Depth_First Traversal:
recursive_preOrder
recursive_inOrder
recursive_postOrder
28
PreOrder Traversal
Algorithm recursive_preOrder (val subroot <pointer>,
ref<void>Operation(ref Data <DataType>))
Traverses a binary tree in node-left-right sequence.
Pre subroot points to the root of a tree/ subtree.
Post each node has been processed in order.
End recursive_preOrder
29
InOrder Traversal
Algorithm recursive_inOrder (val subroot <pointer>,
ref<void>Operation(ref Data <DataType>))
Traverses a binary tree in left-node-right sequence
Pre subroot points to the root of a tree/ subtree
Post each node has been processed in order
End recursive_inOrder
30
30
PostOrder Traversal
Algorithm recursive_postOrder (val subroot <pointer>,
ref<void>Operation(ref Data <DataType>))
Traverses a binary tree in left-right-node sequence
Pre subroot points to the root of a tree/ subtree
Post each node has been processed in order
End recursive_postOrder
31
Depth-First Traversal
<void> preOrderTraverse (ref<void>Operation(ref Data <DataType>))
1. recursive_preOrder(root, Operation)
End preOrderTraverse
34
Breadth-First Traversal
Algorithm BreadthFirstTraverse
(ref<void>Operation(ref Data <DataType>))
1. if (root is not NULL)
1. queueObj <Queue>
2. queueObj.EnQueue(root)
3. loop (not queueObj.isEmpty())
1. queueObj.QueueFront(pNode)
2. queueObj.DeQueue()
3. Operation(pNode->data)
4. if (pNode->left is not NULL)
1. queueObj.EnQueue(pNode->left)
5. if (pNode->right is not NULL)
1. queueObj.EnQueue(pNode->right)
End BreadthFirstTraverse 35
Binary
Binary
Search
Search
Tree
Tree
(BST)
36
Binary
Binary
Search
Search
Tree
Tree
(BST)
BST is one of implementations for ordered list.
37
37
Binary Search Tree (BST)
Auxiliary functions for Search:
recursive_Search
iterative_Search
38
Search node in BST (recursive version)
<pointer> recursive_Search (val subroot <pointer>,
val target <KeyType>)
Searches target in the subtree.
39
Search node in BST (recursive version)
1. if (subroot is NULL) OR (subroot->data = target)
1. return subroot
2. else if (target < subroot->data)
1. return recursive_Search(subroot->left, target)
3. else
1. return recursive_Search(subroot->right, target)
subroot
End recursive_Search
Target = 22
40
Search node in BST (recursive version)
1. if (subroot is NULL) OR (subroot->data = target)
1. return subroot
2. else if (target < subroot->data)
1. return recursive_Search(subroot->left, target)
3. else
1. return recursive_Search(subroot->right, target)
End recursive_Search
subroot
Target = 22
41
Search node in BST (recursive version)
1. if (subroot is NULL) OR (subroot->data = target)
1. return subroot
2. else if (target < subroot->data)
1. return recursive_Search(subroot->left, target)
3. else
1. return recursive_Search(subroot->right, target)
End recursive_Search
subroot
Target = 22
42
Search node in BST (recursive version)
1. if (subroot is NULL) OR (subroot->data = target)
1. return subroot
2. else if (target < subroot->data)
1. return recursive_Search(subroot->left, target)
3. else
1. return recursive_Search(subroot->right, target)
End recursive_Search
subroot
Target = 22
43
Search Node in BST (nonrecursive version)
<pointer> iterative_Search (val subroot <pointer>,
val target <KeyType>)
Searches target in the subtree.
44
Search Node in BST (nonrecursive version)
1. while (subroot is not NULL) AND (subroot->data.key <> target)
1. if (target < subroot->data.key)
1. subroot = subroot->left
2. else
1. subroot = subroot->right
2. return subroot
subroot
End iterative_Search
Target = 22
45
Search Node in BST (nonrecursive version)
1. while (subroot is not NULL) AND (subroot->data.key <> target)
1. if (target < subroot->data.key)
1. subroot = subroot->left
2. else
1. subroot = subroot->right
2. return subroot
End iterative_Search
subroot
Target = 22
46
Search Node in BST (nonrecursive version)
1. while (subroot is not NULL) AND (subroot->data.key <> target)
1. if (target < subroot->data.key)
1. subroot = subroot->left
2. else
1. subroot = subroot->right
2. return subroot
End iterative_Search
subroot
Target = 22
47
Search Node in BST (nonrecursive version)
1. while (subroot is not NULL) AND (subroot->data.key <> target)
1. if (target < subroot->data.key)
1. subroot = subroot->left
2. else
1. subroot = subroot->right
2. return subroot
End iterative_Search
subroot
Target = 22
48
Search node in BST
<ErrorCode> Search (ref DataOut <DataType>)
Searches target in the subtree.
Pre DataOut contains value needs to be found in key field.
Post DataOut will reveive all other values in other fields if that
key is found.
Return success or notPresent
Uses Auxiliary function recursive_Search or iterative_Search
1. pNode = recursive_Search(root, DataOut.key)
2. if (pNode is NULL)
1. return notPresent
3. dataOut = pNode->data
4. return success
End Search 49
50
Search node in BST
The same keys may be built into BST of many different
shapes.
51
Insert Node into BST
52
Question:
Insert Node into BST
??
Can Insert method use recursive_Search or iterative_Search
instead of recursive_Insert like that:
53
Insert Node into BST
Auxiliary functions for Insert:
recursive_Insert
iterative_Insert
54
Recursive Insert
<ErrorCode> recursive_Insert (ref subroot <pointer>,
val DataIn <DataType>)
Inserts a new node into a BST.
1. if (subroot is NULL)
1. Allocate subroot
2. subroot->data = DataIn
3. return success
2. else if (DataIn.key < subroot->data.key)
1. return recursive_Insert(subroot->left, DataIn)
3. else if (DataIn.key > subroot->data.key) DataIn.key = 22
1. return recursive_Insert(subroot->right, DataIn)
4. else
1. return duplicate_error
56
5. End recursive_Insert
Recursive Insert (cont.)
<ErrorCode> recursive_Insert (ref subroot <pointer>,
val DataIn <DataType>)
subroot
1. if (subroot is NULL)
1. Allocate subroot
2. subroot->data = DataIn
3. return success
2. else if (DataIn.key < subroot->data.key)
1. return recursive_Insert(subroot->left, DataIn)
3. else if (DataIn.key > subroot->data.key) DataIn.key = 22
1. return recursive_Insert(subroot->right, DataIn)
4. else
1. return duplicate_error
57
5. End recursive_Insert
Recursive Insert (cont.)
<ErrorCode> recursive_Insert (ref subroot <pointer>,
val DataIn <DataType>)
1. if (subroot is NULL)
subroot
1. Allocate subroot
2. subroot->data = DataIn
3. return success
2. else if (DataIn.key < subroot->data.key)
1. return recursive_Insert(subroot->left, DataIn)
3. else if (DataIn.key > subroot->data.key) DataIn.key = 22
1. return recursive_Insert(subroot->right, DataIn)
4. else
1. return duplicate_error
58
5. End recursive_Insert
Recursive Insert (cont.)
<ErrorCode> recursive_Insert (ref subroot <pointer>,
val DataIn <DataType>)
1. if (subroot is NULL)
1. Allocate subroot
2. subroot->data = DataIn
subroot
3. return success
2. else if (DataIn.key < subroot->data.key)
1. return recursive_Insert(subroot->left, DataIn)
3. else if (DataIn.key > subroot->data.key) DataIn.key = 22
1. return recursive_Insert(subroot->right, DataIn)
4. else
1. return duplicate_error
59
5. End recursive_Insert
Recursive Insert (cont.)
<ErrorCode> recursive_Insert (ref subroot <pointer>,
val DataIn <DataType>)
1. if (subroot is NULL)
1. Allocate subroot
2. subroot->data = DataIn
subroot
3. return success
2. else if (DataIn.key < subroot->data.key)
1. return recursive_Insert(subroot->left, DataIn)
3. else if (DataIn.key > subroot->data.key) DataIn.key = 22
1. return recursive_Insert(subroot->right, DataIn)
4. else
1. return duplicate_error
60
5. End recursive_Insert
Iterative Insert
<ErrorCode> iterative_Insert (ref subroot <pointer>,
val DataIn <DataType>)
Inserts a new node into a BST.
61
Iterative Insert (cont.)
<ErrorCode> iterative_Insert (ref subroot <pointer>,
val DataIn <DataType>)
1. if (subroot is NULL)
1. Allocate subroot subroot
2. subroot->data = DataIn
3. return success
2. else
DataIn.key = 22
62
Iterative Insert (cont.)
<ErrorCode> iterative_Insert (ref subroot <pointer>,
val DataIn <DataType>)
1. if (subroot is NULL)
1. Allocate subroot subroot
2. subroot->data = DataIn
3. return success
2. else
DataIn.key = 22
63
Iterative Insert (cont.)
2. else subroot
pCurr
1. pCurr = subroot
2. loop (pCurr is not NULL)
1. if (pCurr->data.key = DataIn.key)
1. return duplicate_error
2. parent = pCurr
3. if (DataIn.key < parent->data.key)
1. pCurr = parent -> left
4. else
1. pCurr = parent -> right
3. if (DataIn.key < parent->data.key)
1. Allocate parent->left
2. parent->left.data = DataIn DataIn.key = 22
4. else
1. Allocate parent->right
2. parent->right.data = DataIn
5. return success
64
End Iterative_Insert
Iterative Insert (cont.)
2. else parent
subroot
1. pCurr = subroot
2. loop (pCurr is not NULL) pCurr
1. if (pCurr->data.key = DataIn.key)
1. return duplicate_error
2. parent = pCurr
3. if (DataIn.key < parent->data.key)
1. pCurr = parent -> left
4. else
1. pCurr = parent -> right
3. if (DataIn.key < parent->data.key)
1. Allocate parent->left
2. parent->left.data = DataIn DataIn.key = 22
4. else
1. Allocate parent->right
2. parent->right.data = DataIn
5. return success
65
End Iterative_Insert
Iterative Insert (cont.)
2. else subroot
1. pCurr = subroot
2. loop (pCurr is not NULL) parent
1. if (pCurr->data.key = DataIn.key)
1. return duplicate_error pCurr
2. parent = pCurr
3. if (DataIn.key < parent->data.key)
1. pCurr = parent -> left
4. else
1. pCurr = parent -> right
3. if (DataIn.key < parent->data.key)
1. Allocate parent->left
2. parent->left.data = DataIn DataIn.key = 22
4. else
1. Allocate parent->right
2. parent->right.data = DataIn
5. return success
66
End Iterative_Insert
Iterative Insert (cont.)
2. else subroot
1. pCurr = subroot
2. loop (pCurr is not NULL)
1. if (pCurr->data.key = DataIn.key)
1. return duplicate_error parent
2. parent = pCurr
3. if (DataIn.key < parent->data.key)
1. pCurr = parent -> left pCurr
4. else
1. pCurr = parent -> right
3. if (DataIn.key < parent->data.key)
1. Allocate parent->left
2. parent->left.data = DataIn DataIn.key = 22
4. else
1. Allocate parent->right
2. parent->right.data = DataIn
5. return success
67
End Iterative_Insert
Iterative Insert (cont.)
2. else subroot
1. pCurr = subroot
2. loop (pCurr is not NULL)
1. if (pCurr->data.key = DataIn.key)
1. return duplicate_error parent
2. parent = pCurr
3. if (DataIn.key < parent->data.key)
1. pCurr = parent -> left pCurr
4. else
1. pCurr = parent -> right
3. if (DataIn.key < parent->data.key)
1. Allocate parent->left
2. parent->left.data = DataIn DataIn.key = 22
4. else
1. Allocate parent->right
2. parent->right.data = DataIn
5. return success
68
End Iterative_Insert
Insert Node into BST
<ErrorCode> Insert (val DataIn <DataType>)
Inserts a new node into a BST.
End Insert
69
Insert Node into BST
Insertion a new node into a random BST with n nodes
takes O(log n) steps.
70
Delete node from BST
• Deletion of a leaf:
Set the deleted node's parent link to NULL.
71
Delete node from BST
72
Delete node from BST
Replace X by W Delete
original W
W is predecessor
of X
74
Delete node from BST
• Node having both subtrees
75
Delete node from BST
Auxiliary functions for Insert:
recursive_Delete
iterative_Delete
76
Recursive Delete
<ErrorCode> recursive_Delete (ref subroot <pointer>,
val key <KeyType>)
Deletes a node from a BST.
Pre subroot is NULL or points to the root of a subtree. Key contains value
needs to be removed from BST.
Post If key is found, it will be removed from BST.
Return notFound or success.
Uses recursive_Delete and RemoveNode functions.
77
Recursive Delete (cont.)
<ErrorCode> recursive_Delete (ref subroot <pointer>,
val key <KeyType>)
1. if (subroot is NULL)
1. return notFound
2. else if (key < subroot->data.key)
1. return recursive_Delete(subroot->left, key)
3. else if (key > subroot->data.key)
1. return recursive_Delete(subroot->right, key)
4. else
1. RemoveNode(subroot)
2. return success
End recursive_Delete 78
Delete Node from BST
<ErrorCode> Delete (val key <KeyType>)
Deletes a node from a BST.
Pre subroot is NULL or points to the root of a subtree. Key contains value
needs to be removed from BST.
Post If key is found, it will be removed from BST.
Return notFound or success.
Uses recursive_Delete and RemoveNode functions.
End Delete
79
Auxiliary Function RemoveNode
<void> RemoveNode (ref subroot <pointer>, val key <KeyType>)
1. pDel = subroot // remember node to delete at end.
2. if (subroot ->left is NULL) // leaf node or node having only right subtree.
1. subroot = subroot->right // (a) and (b)
3. else if (subroot->right is NULL) // node having only left subtree.
1. subroot = subroot->left
subroot subroot
pDel pDel
(a)
subroot subroot
pDel pDel
(a)
key needs
key needs to
to be
be deleted
deleted == 18
18 (b) 81
Auxiliary Function RemoveNode
<void> RemoveNode (ref subroot <pointer>, val key <KeyType>)
1. pDel = subroot // remember node to delete at end.
2. if (subroot ->left is NULL) // leaf node or node having only right subtree.
1. subroot = subroot->right
3. else if (subroot->right is NULL) // node having only left subtree.
1. subroot = subroot->left // (c)
subroot
pDel
subroot
pDel
End RemoveNode
(d) 84
Auxiliary Function RemoveNode (cont.)
1. else // node having both subtrees. (d)
1. parent = subroot
2. pDel = parent ->left // move left to find the predecessor.
3. loop (pDel->right is not NULL) // pDel is not the predecessor
1. parent = pDel
2. pDel = pDel->right key needs to be deleted = 23
4. subroot->data = pDel->data subroot
5. if (parent = subroot)
1. parent->left = pDel->left
parent
6. else
1. parent->right = pDel->left
7. recycle pDel pDel
End RemoveNode
(d) 85
Auxiliary Function RemoveNode (cont.)
1. else // node having both subtrees. (d)
1. parent = subroot
2. pDel = parent ->left // move left to find the predecessor.
3. loop (pDel->right is not NULL) // pDel is not the predecessor
1. parent = pDel
2. pDel = pDel->right key needs to be deleted = 23
4. subroot->data = pDel->data subroot
5. if (parent = subroot)
1. parent->left = pDel->left
6. else
1. parent->right = pDel->left
7. recycle pDel parent
90