Download Lecture8KS

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

Quadtree wikipedia , lookup

Red–black tree wikipedia , lookup

Interval tree wikipedia , lookup

Lattice model (finance) wikipedia , lookup

Linked list wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
Practicum 2:
- Asymptotics
- List and Tree Structures
15-211
Fundamental Data Structures and
Algorithms
Klaus Sutner
Feb. 5, 2004
Today
Is really easy, just a gentle review of things you already know.
- Asymptotic notation, yet again.
- Implementing nested lists and trees.
Hidden agenda: inductive thinking.
Fudging It
Running time analysis very often leads to more or less intractable
problems: counting steps even in very simple programs is just
hopelessly complicated.
Trying to get precise answers is also really quite useless in most
cases.
It's better to ignore details and focus on the “large picture”.
Upper And Lower Bounds
f(n) = O( g(n) )
f(n) ≤ c g(n)
for some constant c and almost all n
f(n) = ( g(n) )
f(n) ≥ c g(n)
Big-Oh
Big-Omega
for some constant c and almost all n
f(n) = ( g(n) )
Theta
f(n) = O( g(n) ) and f(n) = ( g(n) )
Upper And Lower Bounds
f(n) = O( g(n) )
Big-Oh
can only be used for upper bounds
f(n) = ( g(n) )
Big-Omega
can only be used for lower bounds
f(n) = ( g(n) )
Theta
pins down the running time exactly (up to a multiplicative
constant).
Important Classes
O( 1 )
constant
O( n )
linear
O( n log n )
n-log-n
O( n2 )
quadratic
O( n3 )
cubic
O( 2c n )
exponential (some authors differ)
O( n! )
factorial
Holy Grail
O( nk )
polynomial
versus
O( 2c n )
exponential (some authors differ)
Anything that can be done in polynomial time is
tractable, feasible, doable. But note that there are
constants lurking in the dard.
Empirical Fact: They don't seem to matter much.
Comparison
f(n) = o( g(n) )
lim f(n)/g(n) = 0
Interpretation: g is significantly worse that f.
Example:
f(n) = o( n2 )
sub-quadratic
Often a big challenge to find an algorithm that is sub-xxxx.
Similarity
f(n) ~ g(n)
lim f(n)/g(n) = 1
Interpretation: f and g are essentially indistinguishable.
This is much stronger than .
Example: n ~ n + 1/n
Approximations
Used mostly to assert the quality of an approximation.
Hn ~ log n + 
Here  is the Euler-Mascheroni constant
 ≈ 0.5772156649015328
More Recursive Data
Structures
Inductive thinking is often the best way to tackle complicated
data structures.
Plain linked lists are a cheap example, but not convincing:
everybody knows how to hack linked lists, induction be
damned.
Let's try something more ambitious:
Nested Lists and Binary Trees.
Nested Lists
In an ordinary lists, only atomic elements such as integers can
be stored.
How about allowing lists of lists of lists ... of integers?
( 1, 2, ( 3, 4 ), ((5)), 6 )
How hard would it be to design this type of data structure?
What basic operations should we use?
How does it compare to other structures such as trees?
Basic Operations
1. How do we construct such a nested list?
What is the inductive structure here?
2. Suppose we already have built such a nested list.
What are the access operations we need to get at the pieces?
3. How do we deal with operations such as flattening?
Basic Operations
How do we implement this using Java's language features?
MAW: null is not such a great idea.
In the OO framework everything should be a class,
even an empty list.
The root concept List appears in several incarnations:
empty, with leading int, with leading list.
Basic Structure
There are three cases to consider:
nil
EmptyList
( 12345, (...) )
IntList
( (...), (...) )
NestList
Use a small hierarchy.
Access
We only need the standard first/rest machinery.
Every position in a nested list can be accessed by a sequence of
first/rest operations.
Note that simple iterators don't quite work here: we need to be
able to go forward or down:
( (5,6), 2, 3, 4 )
Flattening
Intuitively, the flatten operation is easy:
( (5,6), 2, ((3)), 4 ) --> (5,6,2,3,4)
Domain: nested lists, codomain: simple lists.
We may assume we have the usual operations on simple lists
available.
So how does flatten act on a nested list?
Flattening
( (5,6), 2, ((3)), 4 ) --> (5,6,2,3,4)
flatten(nil) = nil
flatten( (x,R) ) = prepend( flatten(R), x )
flatten( (L,R) ) = join( flatten(L), flatten(R) )
Binary Trees
Really ordered binary trees: every child is either left or right
(even when the other child is missing).
Information can be stored only at all nodes (for simplicity, let's
just say an integer can be stored).
Intuitively, it should be clear that this DS is more “powerful”
than just linked lists. Right?
Pretty Pictures
nil
Basic Choices
Note that this is really quite similar to the nested list construction.
Again we build a small class hierarchy:
Root concept Tree appears in incarnations:
nil
empty
T(a,L,R)
interior node
Lists as Trees
There is a natural way to represent flat lists as
trees.
Lists as Trees
There is a natural way to represent nested lists as
trees.
How To Convert?
How would a conversion function work?
l2t( nil ) = nil
l2t( (x,R) ) = T( - , T(x,nil,nil), l2t(R) )
l2t( (L,R) ) = T( - , l2t(L), l2t(R) )
How To Convert?
Looks a bit inelegant. Better would be
l2t( nil ) = nil
l2t( (x,R) ) = T( x, l2t(R) )
l2t( (L,R) ) = T( l2t(L), l2t(R) )
What does this require in terms of the trees?
Proper Trees
Note that not every tree can be the result of
converting a nested list.
How do we check whether a tree is obtained by
converting a list?
Let's call these trees proper.
We want a function
proper : trees --> {true,false}
Who'se More Powerful?
It looks like trees are more powerful than
nested lists.
Are they really?
Suppose Fritz Hackmann has this absolutely
fantastic implementation of nested lists.
Francoise Haquer needs a tree implementation,
and fast.
Could she somehow use Fritz's code?
What Does This Mean?
At the very least, we need to be able to convert
trees into nested lists. There has to be an
injective map
t2l : trees --> lists
Let's not worry about efficiency at this point.
--> ( (a,b),c,d,(e))
Converting Back
t2l( nil ) = nil
t2l( T( -, T(x,nil,nil), R ) ) = ( x, t2l(R) )
t2l( T( -, L, R ) ) = ( ( t2l(L) ), t2l(R) )
Take this with a grain of salt, there should be list
operations on the right.
S
hOne More Picture
o
u A 3 by 3 matrix as a tree.
l
d
a
d
d
(
)
b
e