PowerPoint97

MCS680:
Foundations Of
Computer Science
int MSTWeight(int graph[][], int size)
{
int i,j;
int weight = 0;
O(1)
1
n
for(i=0; i<size; i++)
for(j=0; j<size; j++)
n
weight+= graph[i][j];
O(n)
return weight;
1
}
O(n)
O(1)
Running Time = 2O(1) + O(n2) = O(n2)
Tree Analysis
and
Algorithms
Brian Mitchell
([email protected]) -
1
Introduction
• Tree’s can be used to model many
applications in computer science
– Hierarchical structures
– Nested/Embedded structures
• Applications
– Sort trees
– Search trees
– Parse trees
• Mathematical expressions
• Syntax
– Graphics algorithms
– File systems
• Many tree algorithms are simple because
they leverage the structure of the tree
– Recursive algorithms
Brian Mitchell
([email protected]) -
2
Tree Terminology
n1
n2
n4
n3
n5
n6
• A tree consists of a set of Nodes and Edges
• Every tree has a root node
• Every node other than the root is connected
to another node called the parent
• Every node may have zero or more children
• Trees have a connectivity property such that
if we start at any node and move to it’s
parent (repetitively) we will eventually reach
the root of the tree
Brian Mitchell
([email protected]) -
3
Recursive Definition of a Tree
• The structure of a tree leads to a natural
recursive definition of a tree
• Basis
– A single node is a tree, it is also the root of
the tree
• Induction
– Let r be a new node (it is also a tree by the
basis definition)
– Let T1, T2, ..., Tk be one or more trees with
roots c1, c2, ..., ck respectively.
– Now:
• Let r be the root of the tree T
• Add an edge from r to each of the nodes c1,
c2, ..., ck.
– Thus we have made r the root of a new tree
with children consisting of the roots of
trees T1, T2, ..., Tk
Brian Mitchell
([email protected]) -
4
Example Using the Recursive
Definition of a Tree
Define the following tree using the recursive
definition of a tree:
n1
n2
n4
n3
n5
n6
• Basis
– Make nodes n6, n5, n3
• Each is a single node tree (T6, T5 & T3)
– Induction
• Make node n4, connect it to T6, this is a
new tree T4
• Make node n2, connect it to T4 & T5, this is
a new tree T2
• Make node n1, connect it to T2 & T3, this is
a new tree T1
Brian Mitchell
([email protected]) -
5
Paths, Ancestors and
Descendants
• Parent and child relationships can naturally
be converted to ancestors and descendants
– Ancestors
• The ancestors of a node are found by
repetitively following the unique path from
the node to its parent
• A node is also its own ancestor
– Descendant
• Opposite of ancestor relationship
• A node d is a descendant of node a if and
only if a is an ancestor of d
– Path
• Let m1, m2, ... mk be a sequence of nodes in
a tree such that node mi is the parent of
node m(i+1)
• Then m1, m2, ... mk is called a path from m1
to mk in the tree
– The length of the path is (k-1)
– Path of length zero is when k=1
Brian Mitchell
([email protected]) -
6
Subtrees
• In a tree T, a node n, together with all of its
proper descendants (if any) is called a
subtree of T
• Node n is the root of the subtree
• A subtree must satisfy the three properties
of all trees
– A subtree contains a root
– All other nodes in the subtree have a
unique parent in the subtree
– By following parents from any node in the
subtree, we eventually reach the root of the
subtree
• Thus all nodes in tree T, other then the root
node are roots of subtrees in T
Brian Mitchell
([email protected]) -
7
Height and Depth of Trees
• Leaves and Interior Nodes
– A leaf is a node that has no children
– An interior node is a node that has one or
more children
– Every node in the tree is either a leaf or an
interior node -- but not both
– The root of the tree is an interior node
unless it is the only node in the tree
• The root will be a leaf node in this case
• Height of a tree
– The height of node n in a tree is the longest
path from n to a leaf in the tree
– The height of of the tree is the height of the
root
• Depth of a tree
– The depth, or level, of a node n is the
length of the path from the root to n
Brian Mitchell
([email protected]) -
8
Tree Data StructuresParent Node Representation
typedef struct _PTREE
{
int
element;
struct _PTREE
*parent;
}PTREE;
• Some algorithms only require that you can
identify your parent node
• The PTREE data structure allows for trees
to be constructed whereby each node in the
tree knows about its parent
• The root node can have a parent node of
NULL, or a pointer to itself
• This data structure can not be used to
traverse a tree in a downward direction
Brian Mitchell
([email protected]) -
9
Tree Data Structures Child Array Representation
#define MAX_DEGREE
10
typedef struct _CATREE
{
int
element;
struct _CATREE *children[MAX_DEGREE];
}CATREE;
• This data structure uses an array of
CATREE pointers to point to the children
of a node
– Use a NULL pointer in the children array
to indicate that the array position does not
point to any children
• Must know in advance the maximum
number of children that any possible node
can have
• There is a lot of wasted space if most of
the nodes do not have many children
Brian Mitchell
([email protected]) -
10
Tree Data Structures Child Linked List Representation
typedef struct _CLIST
{
struct _CPTREE *node;
struct _CLIST
*nextChild;
}
typedef struct _CPTREE
{
int
element;
struct _CLIST
*childList;
}CPTREE;
• This data structure uses a linked list to
manage the children of a node in the tree
• Efficient use of space
• No upper bound for the number of children
that any given node can have
• Might be a little slow because traversing a
linked list takes O(1) time
– Child linked list must be traversed for each
node evaluation
Brian Mitchell
([email protected]) -
11
Tree Data StructuresLeft-Child, Right-Sibling
typedef struct _LCRSTREE
{
int
element;
struct _LCRSTREE
*leftChild;
struct _LCRSTREE
*rightSibling;
}LCRSTREE;
• Very efficient representation for a tree
– Commonly used representation
• Each node in the tree knows about its
leftmost child and its nearest rightmost
sibling
• No wasted space
• Small data structure
• Easy to implement
• Easy to traverse tree
Brian Mitchell
([email protected]) -
12
Example Tree Representation
Left Child, Right Sibling
Consider the following tree:
n1
n2
n4
n3
n5
n6
Using a left child, right sibling representation, the
above tree would be represented as follows:
n1
n2
n4
n3
n5
n6
Brian Mitchell
([email protected]) -
13
Tree Data StructuresUsing Parent Pointers
typedef struct _LCRSTREE
{
int
element;
struct _LCRSTREE
*parentNode;
struct _LCRSTREE
*leftChild;
struct _LCRSTREE
*rightSibling;
}LCRSTREE;
• Sometimes it is desirable to integrate a
parent pointer into the tree representation
• Allows for algorithms that need to move
down or backtrack up the tree without
having to remember previous, or historical
pointers
• Simple modification to basic data structure
by adding a parent pointer to the data
structure
Brian Mitchell
([email protected]) -
14
Recursion on Trees
n
c1
c2
c3
...
ck
• The usefulness of trees is highlighted by the
number of recursive operations and
algorithms that exist for tree processing
• Every node in a tree is either an interior
node or a leaf
– A leaf node is the simplest form of a tree
because leaf nodes do not have any children
• The basis case
– Interior nodes have children, and each child
is a subtree in the main tree. Each subtree in
the main tree is a simpler tree
• The inductive definition
Brian Mitchell
([email protected]) -
15
Recursively Traversing a Tree
Preorder Visiting
+
a
*
-
b
d
c
• Preorder traversal
– Print the node
– Explore the left subtree until you can’t
explore any more
– Explore the siblings of the lowest subtree
that you can find in a preorder fashion
– Sample Tree: +a*-bcd
Brian Mitchell
([email protected]) -
16
Recursively Traversing a Tree
Postorder Visiting
+
a
*
-
b
d
c
• Postorder traversal
– Explore the left subtree until you can’t
explore any more
– Print the node
– Explore the siblings of the lowest subtree
that you can find in a postorder fashion
– Sample Tree: abc-d*+
Brian Mitchell
([email protected]) -
17
Recursively Searching a Tree
Preorder Algorithm
typedef struct _LCRSTREE
{
int
element;
struct _LCRSTREE
*leftChild;
struct _LCRSTREE
*rightSibling;
}LCRSTREE;
void Preorder(LCRSTREE *T)
{
printf(“%d “,T->element);
T = T->leftChild;
while (T != NULL)
{
Preorder(T);
T = T->rightSibling;
}
}
Brian Mitchell
([email protected]) -
18
Structural Induction
• Recall, Inductive Proofs
– Show a basis case
– Assume that the induction holds for f(n)
– Show that the inductive hypothesis holds
for f(n+1)
• Structural Induction on Trees
– Basis Case: Show that S(T) is true when T
consists of a single node
– Inductive Hypothesis:
• Assume T is a tree with root r and children
c1, c2, ... ck for some k > 1
• Let T1, T2, ... Tk be the subtrees of T rooted
at c1, c2, ... ck respectively
• Assume that S(T1), S(T2), ... S(Tk) is true
– Assuming that the inductive hypothesis is
true for subtrees S(T1), S(T2), ... S(Tk) in T,
show that S(T) is also true
Brian Mitchell
([email protected]) -
19
Recursively Searching a Tree
Postorder Algorithm
typedef struct _LCRSTREE
{
int
element;
struct _LCRSTREE
*leftChild;
struct _LCRSTREE
*rightSibling;
}LCRSTREE;
void Postorder(LCRSTREE *T)
{
T = T->leftChild;
while (T != NULL)
{
Postorder(T);
T = T->rightSibling;
}
printf(“%d “,T->element);
}
Brian Mitchell
([email protected]) -
20
Structural Induction Proof
Example - ComputeHt()
typedef struct _LCRSTREE
{
int
element;
int
height;
struct _LCRSTREE
*leftChild;
struct _LCRSTREE
*rightSibling;
}LCRSTREE;
void ComputeHt(LCRSTREE *n)
{
LCRSTREE
*c;
(1) n->height = 0;
(2) c = n->leftChild;
(3) while (c != NULL)
{
(4)
ComputeHt(c);
(5)
if (c->height >= n->height)
(6)
n->height = c->height++;
(7)
}
}
c = c->rightSibling;
Brian Mitchell
([email protected]) -
21
Structural Induction Proof
Example - ComputeHt()
• Prove that when ComputeHt() is called on
a pointer to the root of tree T, the correct
height of each node n is stored in the
height field of that node
• Basis:
– If T consists of a single node then the
leftChild pointer will be NULL
– Thus the while loop never executes
– The only line of code that is run is:
• n->height = 0;
– Thus the height of a single node tree is zero
• Induction:
– Suppose that r is the root of a tree T that is
not a single node.
– By the inductive hypothesis we can assume
that when ComputeHt() is recursively
called at line 4 that the correct height is
installed in the height field
Brian Mitchell
([email protected]) -
22
Structural Induction Proof
Example - ComputeHt()
• Induction (con’t)
– We now need to show that the while loop
(lines 3 - 7) correctly sets n->height to one
more than the maximum of the heights of
the children on n
– We show this by performing another
induction on the number of times that the
while loop is executed
• Second Induction: Show that after the
while loop (lines 3-7) has been executed i
times that the value of n->height is one
more than the largest of the heights of the
first i children of n
– Basis:
• The basis is i = 1
• The loop is never entered if i = 0 because
there are no children
• If i = 1 the loop is executed 1 time
Brian Mitchell
([email protected]) -
23
Structural Induction Proof
Example - ComputeHt()
• Second Induction (con’t)
– Basis (con’t)
• The loop is executed one time and the
height is initialized to zero prior to entering
the loop
• Therefore the if statement on line 5 is
executed once
– The if statement sets n->height to one more
then the height of the child
– Induction
• Assume that S’(i) is true
– After i iterations of the loop, n->height is
one larger then the largest height among the
first i children
• If there is an (i+1)st child then the while
loop condition at line 3 will be true and we
execute the body of the loop an (i+1)st time
– If the (i+1)st child is less then 1 plus the
largest of the first i heights then no change
to n->height will be made
» The if statement at line 5
Brian Mitchell
([email protected]) -
24
Structural Induction Proof
Example - ComputeHt()
• Second Induction (con’t)
– Inductive Step (con’t)
• Once again we are assuming that an (i+1)st
child exists
– We previously showed that no change to
n->height will take place if the (i+1)st child
is not one larger then n->height
– However, if if the (i+1)st child height is
larger then n->height then the if statement
on line 5 will be executed and n->height
will be set to one larger then the (i+1)st
child height
• Thus we have shown by induction on the
number of children of a given node that the
while loop (lines 3-7) will in fact set
n->height to one larger then the maximum
height of all of n’s children
• Now we must return to the original
induction
Brian Mitchell
([email protected]) -
25
Structural Induction Proof
Example - ComputeHt()
• Original Induction Revisited
– When the condition on the while loop
(line 3) fails we have evaluated all of the
children of n
– The second induction, S’(i), showed that
when i is the total number of children of n
that n->height is one more then the height of
the largest height of all of the children on n
– By the original inductive hypothesis we
assume that the correct height is stored in
each child node of r
– Now assume that we apply the second
induction to all of the children of r
• The second induction showed us that if we
apply the induction on all of the children of r,
that r’s height will be one more than the
maximum height of all of the children of r
– Thus by structural induction r’s height will
be the height of the tree T
Brian Mitchell
([email protected]) -
26
Special Trees
• Binary Tree
– Special type of tree because the maximum
number of children that any node can have
is two
– Many algorithms exist for organizing and
processing data using binary trees
•
•
•
•
Heaps and Heap Sorts
Priority Queues
Binary Search
Expression Parsing & Evaluation
– Many of the algorithms on binary trees run
proportional to lg n time
• Very efficient algorithms
– Can develop simpler algorithms for tree
processing if the tree is a binary tree
• Do not need to walk the rightSibling linked
list for each node because every node has at
most two children
– Left Child and Right Child
Brian Mitchell
([email protected]) -
27