Download CE221_week_5_Chapter4_TreesBinary

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Linked list wikipedia , lookup

Quadtree wikipedia , lookup

Lattice model (finance) wikipedia , lookup

Red–black tree wikipedia , lookup

B-tree wikipedia , lookup

Interval tree wikipedia , lookup

Binary tree wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
CE 221
Data Structures and
Algorithms
Chapter 4: Trees (Binary)
Text: Read Weiss, §4.1 – 4.2
Izmir University of Economics
1
Preliminaries - I
• (Recursive) Definition: A tree is a collection
of nodes. The collection can be empty;
otherwise, a tree consists of a distinguished
node r, called the root, and zero or more
nonempty (sub)trees T1, T2, ..., Tk, each of
whose roots are connected by a directed
edge from r. The root of each subtree is
said to be a child of r, and r is the parent of
each subtree root.
Izmir University of Economics
2
Preliminaries - II
• Observation: For a tree with N nodes, there
are N-1 edges.
• Proof: Each edge connects a node to its
parent and every node except the root has
one parent.
Izmir University of Economics
3
Preliminaries - III
• The root is A. Node F has A as a parent and K, L,
and M as children. Each node may have an
arbitrary number of children, possibly zero. Nodes
with no children are known as leaves (leaf node).
B, C, H, I, P, Q, K, L, M, and N are leaves. Nodes
with the same parent are siblings; thus K, L, and
M are all siblings. Grandparent and grandchild
relations can be defined in a similar manner.
Izmir University of Economics
4
Preliminaries - IV
• A path from node n1 to nk is defined as a sequence of
nodes n1, n2, ..., nk such that ni is the parent of ni+1 for 1 ≤ i <
k. The length of this path is the number of edges on the
path, namely k - 1. There is a path of length zero from every
node to itself. Notice that there is exactly one path from the
root to each node.
• For any node ni, the depth of ni is the length of the unique
path from the root to ni. Thus, the root is at depth 0. The
height of ni is the length of the longest path from ni to a leaf.
Thus all leaves are at height 0. The height of a tree is equal
to the height of the root. The depth of a tree is equal to the
depth of the deepest leaf which is always equal to the height
of the tree. If there is path from n1 to n2 (n1≠n2), then n1 is an
(proper) ancestor of n2 and n2 is a (proper) descendant of
n1.
Izmir University of Economics
5
Implementation of Trees
• One way is to have in each node besides its data,
a link to to each child of that node. However, since
the number of children per node can vary greatly
and is not known in advance, it might be infeasible.
The solution is simple: keep the children in a linked
list of tree nodes.
Izmir University of Economics
6
Tree Traversals with an Application - I
• One popular use is the directory structure in many common
operating systems.
• The root of this directory is /usr. (The asterisk next to the
name indicates that /usr is itself a directory.) /usr has three
children, mark, alex, and bill, which are themselves
directories. Thus, /usr contains three directories and no
regular files. The filename /usr/mark/book/ch1.r is obtained
by following the leftmost child three times. Each / after the
first indicates an edge; the result is the full pathname.
Izmir University of Economics
7
Tree Traversals with an Application - II
• Suppose we would like to list the names of all of the files in the
directory. Our output format will be that files that are at depth d will
have their names indented by d tabs. The strategy below is known as
preorder traversal. In a preorder traversal, work at a node is
performed before (pre) its children. If there are N file names, then the
running time is O(N).
void list_directory (DirEntry* D){
listAll ( D, 0 );
}
void listAll (DirEntry* D, unsigned int depth){
if ( D != NULL){
printName ( depth, D->name );
if( isDirectory(D))
for each child c of D
listAll ( c, depth+1 );
}
}
Izmir University of Economics
8
Tree Traversals with an Application - III
• Another common method of traversing a tree is the postorder traversal.
With it, the work at a node is performed after (post) its children are
evaluated. As an example, the same directory structure as before, is
represented with the numbers in parentheses (the number of disk blocks
taken up by each file). Since the directories are themselves files, they have
size too. The running time of calculating the size each node is O(N) again.
unsigned int size(DirEntry* D){
unsigned int totalSize = 0;
if(D != NULL){
totalSize=sizeOfThisFile(D);
if( isDirectory(D) )
for each child c of D
totalSize += size( c );
}
return( totalSize );
}
Izmir University of Economics
9
Binary Trees
• A binary tree is a tree in which no node can have more
than two children. Subtrees TL and TR which could both be
possibly empty. The depth of an average binary tree is
considerably smaller than N ( actually O( N ) ). For a
special type of binary tree, namely the binary search tree,
the average value of depth is O (log N). Unfortunately it can
be as large as N - 1.
Izmir University of Economics
10
Implementation
• Because a binary tree has at most two children, we
can keep direct links to them. The declaration of tree
nodes is similar in structure to that for doubly linked
lists, in that a node is a structure consisting of the
element information plus two pointers (left and right) to
other nodes.
• Trees are generally drawn as circles connected by
lines. NULL links are not explicitly drawn.
typedef struct tree_node *tree_ptr; •
struct tree_node
{
•
element_type element;
tree_ptr left;
tree_ptr right;
};
typedef tree_ptr TREE;
Why? A binary tree with N
nodes, has N+1 NULL links.
Proof: Ni: #nodes with i children
N0+N1+N2=N (1) // #nodes
N1+2*N2=N-1 (2) // #edges
multiply (1) by 2 and subtract (2)
2*N0+N1=2*N-(N-1)=N+1
Izmir University of Economics
11
An Example: Expression Trees
• The leaves of an expression tree are operands, such as
constants or variable names, and the other nodes contain
operators. Operator nodes might have 1 (unary minus), 2,
or more than two children. We can evaluate an expression
tree, T, by applying the operator at the root to the values
obtained by recursively evaluating the left and right subtrees.
• Inorder traversal: produce an infix expression by first
recursively processing left, then, output the operator at the
root, and finally recursively process the right.
•the left subtree evaluates to
a + (b * c) and
•the right subtree evaluates to
((d *e) + f )*g.
•The entire tree therefore represents
(a + (b*c)) + (((d * e) + f)* g).
Izmir University of Economics
12
Constructing an Expression Tree - I
• We now give an algorithm to convert a postfix
expression into an expression tree. Since we
already have an algorithm to convert infix to postfix,
we can generate expression trees from the two
common types of input. The method we describe
strongly resembles the postfix evaluation algorithm
of Section 3.2.3.
stack=;
while (!EndOf(expression)){
read(ch);
if (isOperand(ch))
push(MakeNode(ch, NULL, NULL), stack);
MakeNode(data,left,right)
else if (isOperator(ch)){
creates a struct
tree_node and returns a
T1=topAndPop(stack);
pointer to it
T2=topAndPop(stack);
push(MakeNode(ch, T2, T1), stack);
}
}
Izmir University of Economics
13
Constructing an Expression Tree - II
As an example, suppose the input is: a b + c d e + * *
ab+cde+**
ab+cde+**
ab+cde+**
ab+cde+**
Izmir University of Economics
14
Constructing an Expression Tree - III
ab+cde+**
ab+cde+**
Izmir University of Economics
15
Homework Assignments
• 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.8, 4.31, 4.33,
4.40, 4.43, 4.45,
• You are requested to study and solve the
exercises. Note that these are for you to
practice only. You are not to deliver the
results to me.
Izmir University of Economics
16