0% found this document useful (0 votes)
44 views84 pages

Binary Trees

The document discusses binary trees and their properties. It defines key concepts like nodes, children, edges, parents, ancestors, descendants, paths, depth, height, levels, leaf nodes, internal nodes, and subtrees. It provides examples and notation for binary trees. It also discusses properties like full binary trees and complete binary trees.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views84 pages

Binary Trees

The document discusses binary trees and their properties. It defines key concepts like nodes, children, edges, parents, ancestors, descendants, paths, depth, height, levels, leaf nodes, internal nodes, and subtrees. It provides examples and notation for binary trees. It also discusses properties like full binary trees and complete binary trees.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd

CSE 203: Data Structures

Elementary Data Structures


Binary Trees
Binary Trees
A binary tree is made up of a finite set of
nodes. This set either is empty or consists
of a node called the root together with two
binary trees, called the left and right
subtrees, which are disjoint from each
other and from the root.
Binary Tree Example
Notation: Node,
children, edge, Root

parent, ancestor,
descendant, path,
depth, height, level,
leaf node, internal
node, subtree.
Binary Tree Example
Notation: Node,
children, edge,
parent, ancestor,
descendant, path,
depth, height, level,
leaf node, internal
node, subtree.
Binary Tree Example
Notation: Node,
children, edge, Left Child
parent, ancestor, of A
Right Child
descendant, path, of A

depth, height, level,


leaf node, internal
node, subtree. Right
Child
Does B have a child??? of B

B has an empty child!!


Binary Tree Example
Parent of B and C
Notation: Node,
children, edge,
parent, ancestor,
Parent of D
descendant, path,
depth, height, level,
leaf node, internal
node, subtree.
Binary Tree Example
Notation: Node,
children, edge, A,C,E,G is a path
parent, ancestor,
descendant, path,
depth, height, level,
leaf node, internal
node, subtree.
If n_1, n_2, ..., n_k is a sequence of
nodes in the tree such that n_i is the
parent of n_i + 1 for 1 ≤ i < k, then this
sequence is called a path from n_1 to
n_k.
Binary Tree Example
Notation: Node, Ancestors of G
children, edge, A,C,E,G is a path
parent, ancestor,
descendant, path,
depth, height, level, Ancestor
of H
leaf node, internal
node, subtree.
If n_1, n_2, ..., n_k is a sequence of
nodes in the tree such that n_i is the
parent of n_i + 1 for 1 ≤ i < k, then this
sequence is called a path from n_1 to
n_k.
Binary Tree Example
Notation: Node, Descendant of A
children, edge, A,C,E,G is a path
parent, ancestor,
descendant, path,
depth, height, level,
leaf node, internal
node, subtree.
If n_1, n_2, ..., n_k is a sequence of
nodes in the tree such that n_i is the
parent of n_i + 1 for 1 ≤ i < k, then this
sequence is called a path from n_1 to
Descendant
n_k. of C
Binary Tree Example
Notation: Node,
children, edge,
0
parent, ancestor, 0

descendant, path,
depth, height, level, 1 1 1

leaf node, internal


node, subtree. 2 2 2 2

3+1=4 3 3 3
Depth of a node…
3
Level of a node…

Height of a tree
Binary Tree Example
Notation: Node,
children, edge, parent,
ancestor, descendant,
path, depth, height,
level, leaf node,
internal node, subtree.
Internal node: At least one non-empty children

Leaf node: nodes having both children empty


Binary Tree Example
Notation: Node, Right subtree of A

children, edge, parent,


ancestor, descendant,
path, depth, height,
level, leaf node,
internal node, subtree.

Left subtree of A
Are the following two trees same?
Full and Complete Binary Trees
Full binary tree: Each node is either a leaf or
internal node with exactly two non-empty children.
Complete binary tree: If the height of the tree is d,
then all leaves except possibly level d-1 are
completely full. The bottom level has all nodes to
the left side.

Full Not anymore Complete Not anymore


Full and Complete Binary Trees
Full binary tree: Each node is either a leaf or
internal node with exactly two non-empty children.
Complete binary tree: If the height of the tree is d,
then all leaves except possibly level d-1 are
completely full. The bottom level has all nodes to
the left side.
One Crucial Observation

NOT NOT FULL


COMPLETE

Full Complete
Full Binary Tree Theorem (1)
Theorem: The number of leaves in a non-empty
full binary tree is one more than the number of
internal nodes.
Proof (by Mathematical Induction):
Base case: A full binary tree with 1 internal node must
have two leaf nodes.
Induction Hypothesis: Assume any full binary tree T
containing n-1 internal nodes has n leaves.
Full Binary Tree Theorem (2)
Induction Step:
We want to prove the following here:

If n-1 internal leaves means n leaves


Then n internal leaves would mean n+1 leaves

[Recall that this will establish the chain:


1 IN means 2 L
So, 2 IN means 3 L
So, 3 IN means 4
And so on…]
Full Binary Tree Theorem (2)

Induction Step: Given tree T


with n internal nodes, pick n INs
internal node I with two leaf
children. Remove I’s children,
call resulting tree T’.
Clearly, T’ is a full binary tree with X is now an LN
n-1 internal nodes Þ now, n-1 INs
X Þ n LN (IH)
By induction hypothesis, it has n
leaves.
Now:
Restore I’s two children. The
number of internal nodes has make X
now gone up by 1 to reach n. a LN X is now an IN
The number of leaves has also Þ now, n INs
gone up by 1. How many LNs?
X
X: IN=> LN
2 LNs added
=> LN increases by 1
IN = Internal Node
=> n+1 (from IH)
LN = Leaf Node Restore the two
IH = Induction Hypothesis children of X
Why Full Binary Tree Theorem is useful?

• Some binary tree implementations store data


only at the leaf nodes, using the internal
nodes to provide structure to the tree.
• More generally, binary tree implementations
might require some amount of space for
internal nodes, and a different amount for leaf
nodes.
Full Binary Tree Corollary
Theorem: The number of empty subtrees in a non-empty binary tree is one more than the
number of nodes in the tree.
Proof :
• Take an arbitrary binary tree T and replace every empty subtree with a leaf node. Call the
new tree T0.
• All nodes originally in T will be internal nodes in T0 (Why?)
• T0 is a full binary tree, because every internal node of T now must have two children in T0,
and each leaf node in T must have two children in T0 (the leaves just added).
• The Full Binary Tree Theorem tells us that the number of leaves in a full binary tree is one
more than the number of internal nodes.
• Thus, the number of new leaves that were added to create T0 is one more than the
number of nodes in T.
• Each leaf node in T0 corresponds to an empty subtree in T. Thus, the number of empty
subtrees in T is one more than the number of nodes in T.
Full Binary Tree Corollary
Theorem: The number of empty subtrees in a non-empty binary
tree is one more than the number of nodes in the tree.
Another Proof :
We prove that a binary tree with n nodes has n+1 empty
subtrees
By definition, every node in binary tree T has two children (some
may be empty)
ÞA total of 2n children in a tree of n nodes.
ÞEvery node except the root node has one parent.
ÞA total of n - 1 nodes with parents.
ÞIn other words, there are n - 1 non-empty children.
ÞBecause the total number of children is 2n, the remaining n + 1
children must be empty.
Binary Tree Node Class
Traversal of Trees
Any process for visiting the nodes in some order is
called a traversal.
A traversal of a tree T is a systematic way of visiting
all the nodes of T
Traversing a tree involves visiting the root and
traversing its subtrees
Mainly, there are the following traversal methods:
 Preorder Traversal (applicable for any tree)
 Postorder Traversal (applicable for any tree)

 Inorder Traversal (of a binary tree)

 Any traversal that lists every node in the tree exactly once
is called an enumeration of the tree’s nodes.
23
Preorder Traversal
• In a preorder traversal, a node is
visited before its descendants
Algorithm preOrder(v)
• If a tree is ordered, then the
subtrees are traversed according visit(v)
to the order of the children for each child w of v
• We assume a left to right order preOrder (w)
1 A

2 9
B
5 C D

3 4 6 7 8
E F I G H

Preorder: ABEFCIGHD
Note: this is not a binary tree
Postorder Traversal
• In a postorder traversal, a Algorithm postOrder(v)
node is visited after its
for each child w of v
descendants
postOrder (w)
visit(v)

A 9
8
3
B 7 C D

1 2 6
4 5
E F I G H

Postorder: EFBIGHCDA
Note: this is not a binary tree
Inorder Traversal
• In an inorder traversal a node Algorithm inOrder(v)
is visited after its left subtree if isInternal (v)
inOrder (leftChild (v))
and before its right subtree:
– Traverse the left subtree in inorder.
visit(v)
– Visit the root. if isInternal (v)
– Traverse the right subtree in inorder. inOrder (rightChild (v))

3 4
8
6 1 9
6
2 8 2 7
5
1 4 7 9
Inorder: DGBAHEICF
3 5
Note: Only applicable to a binary tree 26
Level Order Traversal
• In a level order traversal, every node on a level is
visited before going to a lower level
1 A

2 4
B
3 C D

5 6 7 8 9
E F I G H

Level order: ABCDEFIGH

27
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Pre-Order Traversal
1. A
2. B
3. D
4. C
5. E
6. G
7. F
8. H
9. I
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
Post-Order Traversal
1. D
2. B
3. G
4. E
5. H
6. I
7. F
8. C
9. A
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
In-Order Traversal
1. B
2. D
3. A
4. G
5. E
6. C
7. H
8. F
9. I
Pre-Order Traversal Code V1
/** @param rt The root of the subtree */
void preorder(BinNode rt)
{
if (rt == null) return; // Empty subtree
visit(rt);
preorder([Link]());
preorder([Link]());
}
Pre-Order Traversal Code V2
/** @param rt The root of the subtree */
void preorder2(BinNode rt) // Not so good
{
visit(rt);
if ([Link]() != null) preorder([Link]());
if ([Link]() != null) preorder([Link]());
}
Preorder vs preorder2
• preorder2 makes only half as many recursive
calls. (Why?)
• On the other hand, preorder2 must access the
left and right child pointers twice as often.
• The net result is little or no performance
improvement.
void preorder(BinNode rt)
{
if (rt == null) return; // Empty subtree
visit(rt);
preorder([Link]());
preorder([Link]());
}

void preorder2(BinNode rt) // Not so good


{
visit(rt);
if ([Link]() != null) preorder([Link]());
if ([Link]() != null) preorder([Link]());
}
Preorder2 is inferior
• First, for more complex traversals it can become
awkward to place the check for the NULL pointer
in the calling code.
– Even here we had to write two tests for NULL, rather
than the one needed by preorder.
• The more important concern with preorder2 is
that it tends to be error prone.
– While preorder2 insures that no recursive calls will be
made on empty subtrees, it will fail if the initial call
passes in a NULL pointer.
Recursion Example: Counting the
nodes
• We wish to count the number of nodes in a binary tree.
– How?
• The key insight is that the total count for any (non-empty) subtree
is one for the root plus the counts for the left and right subtrees.

int count(BinNode rt) {


if (rt == null) return 0;
return 1 + count([Link]()) +
count([Link]());
}
Binary Tree Implementation: ‘Key’ Value
• We do not want to describe what we are looking for by
detailing and matching the entire contents of the record.
• If we knew everything about the record already, we
probably would not need to look for it.
• Instead, we typically define what record we want in
terms of a key value.
• For example, if searching for payroll records, we might
wish to search for the record that matches a particular
ID number.
• The ID number is then the search ‘key’.
Binary Tree Implementation

C++[Link]
Binary Tree Implementation
Binary Tree Implementation
Some important issues
• whether the same class definition will be used for
leaves and internal nodes.
– Using the same class for both will simplify the
implementation,
– but might be an inefficient use of space.
– Some applications require data values only for the leaves.
– Other applications require one type of value for the leaves
and another for the internal nodes.
– Also, it seems wasteful to store child pointers in the leaf
nodes.
Binary Tree Implementation

4x (2x + a) + c
4 * x * (2 * x + a) + c
Binary Tree Implementation
• Internal nodes store operators
– could store a small code identifying
the operator (a single byte for the
operator’s symbol)
• the leaves store operands
– i.e., variable names or numbers,
4x (2x + a) + c (considerably larger in order to
4 * x * (2 * x + a) + c handle the wider range of possible
values)
– No child pointers though
Different nodes implementation with
inheritance (1)

C++[Link]
Different nodes implementation with
inheritance (2)

C++[Link]
Why two Implementations?
[Design Patterns]
• Design patterns capture reusable pieces
of design wisdom.
• Goals:
– Quickly communicate design wisdom to new
designers
– Give a shared vocabulary to designers
• WE WILL NOT FOCUS ON THIS
Space Requirements
• Every node has two pointers to its children
• total space = n(2P + D) for a tree of n nodes
– P: space required by a pointer
– D: amount of space required by a data value
• So, total overhead: 2Pn
• Overhead fraction: 2P/(2P+D)
• P = D => 2/3rd of its total space is overhead
• From the Full Binary Tree Theorem: Half of the
pointers are null.
– half of the pointers are “wasted” NULL values that serve only to
indicate tree structure, but which do not provide access to new
data.
Space Overhead
• A common implementation is not to store any
actual data in a node
– but rather a pointer to the data record.
• In this case, each node will typically store
three pointers all of which are overhead:
– overhead fraction of 3P/(3P + D)
– P = D => 3/4th of its total space is overhead
Space Overhead
• If only leaves store data values, then the fraction of
total space devoted to overhead depends on
whether the tree is full.
– If the tree is not full, then conceivably there might only
be one leaf node at the end of a series of internal nodes.
– Thus, the overhead can be an arbitrarily high percentage
• The overhead fraction drops as the tree becomes
closer to full, being lowest when the tree is truly full.
– In this case, about one half of the nodes are internal.
Space Overhead
Eliminate pointers from the leaf nodes:

= Full Binary Tree


n/2(2P) P
n/2(2P) + Dn P+D n/2 IN has 2P
0 P in L
n/2 IN has D
This is 1/2 if P = D. ~n/2 L has D
Space Overhead
If data only at leaves with Full Binary Tree

pointers eliminated n/2 IN has 2P


(2P)/(2P + D)  2/3 overhead ~n/2 L has D

(Assuming P=D).
Note that some method is
needed to distinguish leaves
from internal nodes. So some
space is needed here which
we ignore in our analysis
Space Overhead
• a better implementation would have the
internal nodes store two pointers and no data
field while the leaf nodes store only a pointer
to the data field.
– (3P)/(3P + D) => ¾ when D = P. Full Binary Tree

n/2 IN has 2P
~n/2 L has 1P
~n/2 L has 1D
Array Implementation
Complete Binary Tree

Position 0 1 2 3 4 5 6 7 8 9 10 11
Parent -- 0 0 1 1 2 2 3 3 4 4 5
Left Child 1 3 5 7 9 11 -- -- -- -- -- --
Right Child 2 4 6 8 10 -- -- -- -- -- -- --
Left Sibling -- -- 1 -- 3 -- 5 -- 7 -- 9 --
Right Sibling -- 2 -- 4 -- 6 -- 8 -- 10 -- --
Array Implementation
Position 0 1 2 3 4 5 6 7 8 9 10 11
Parent -- 0 0 1 1 2 2 3 3 4 4 5
Left Child 1 3 5 7 9 11 -- -- -- -- -- --
Right Child 2 4 6 8 10 -- -- -- -- -- -- --
Left Sibling -- -- 1 -- 3 -- 5 -- 7 -- 9 --
Right Sibling -- 2 -- 4 -- 6 -- 8 -- 10 -- --
Array Implementation
Position 0 1 2 3 4 5 6 7 8 9 10 11
Parent -- 0 0 1 1 2 2 3 3 4 4 5
Left Child 1 3 5 7 9 11 -- -- -- -- -- --
Right Child 2 4 6 8 10 -- -- -- -- -- -- --
Left Sibling -- -- 1 -- 3 -- 5 -- 7 -- 9 --
Right Sibling -- 2 -- 4 -- 6 -- 8 -- 10 -- --
Array Implementation
Position 0 1 2 3 4 5 6 7 8 9 10 11
Parent -- 0 0 1 1 2 2 3 3 4 4 5
Left Child 1 3 5 7 9 11 -- -- -- -- -- --
Right Child 2 4 6 8 10 -- -- -- -- -- -- --
Left Sibling -- -- 1 -- 3 -- 5 -- 7 -- 9 --
Right Sibling -- 2 -- 4 -- 6 -- 8 -- 10 -- --
Array Implementation
Position 0 1 2 3 4 5 6 7 8 9 10 11
Parent -- 0 0 1 1 2 2 3 3 4 4 5
Left Child 1 3 5 7 9 11 -- -- -- -- -- --
Right Child 2 4 6 8 10 -- -- -- -- -- -- --
Left Sibling -- -- 1 -- 3 -- 5 -- 7 -- 9 --
Right Sibling -- 2 -- 4 -- 6 -- 8 -- 10 -- --
Array Implementation
Position 0 1 2 3 4 5 6 7 8 9 10 11
Parent -- 0 0 1 1 2 2 3 3 4 4 5
Left Child 1 3 5 7 9 11 -- -- -- -- -- --
Right Child 2 4 6 8 10 -- -- -- -- -- -- --
Left Sibling -- -- 1 -- 3 -- 5 -- 7 -- 9 --
Right Sibling -- 2 -- 4 -- 6 -- 8 -- 10 -- --

You might also like