

Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Data Structures, Exercises Solution - Computer Science - Prof Jonathan Shewchuk.pdf, Computer Science, University of California, USA, Prof. Jonathan Shewchuk, Computer Science, Data Structures, Insertion Sort, Selction Sort, Merge Sort, Qucik Sort
Typology: Exercises
1 / 3
This page cannot be seen from the preview
Don't miss anything!


practice.sol
Selected Solutions (Practice for the Final Exam) [a]^ insertion
sort 7180829417808294017882940127889401247889 [b]^ selection
sort 718082940187829401278894012488970124789801247889 [c]^ mergesort 71808294 17,80,829417,08,829417,08,28,9417,08,28,490178,28,490178,2489 01247889 [d]^ quicksort 718082942180879421088794 210|4|87980|12|4|8798012|4|7898012|4|7|8|98 01247889 [e]^ heapsort 71808294
|^ bottomUpHeap() 82897104
Extend each item so that
it^ has
a^ "secondary
key,"
which
is^ the
index
of
the item in the initial
array/list.
If^ two^ items
have the^ same^ primary
key, the tie is broken
using
the^ secondary
key, so^ no
two^ items are^ ever
considered equal.
[a]^
abdcegfhi BFS:^
abcdegifh [b]^
efihgcdba [c]^ gh, ac, hi, ab, cd,
cg,^ fg,^ ce
(cg
may^ come^ before
cd^ instead)
[a]^ [i]^
[ii]
[b]^ Visited in preorder.
Finished
in^ postorder.
[c]^ With BFS, it’s done
exactly
the^ same^ as^ with
(See Homework 9 for
a^ description
of^ how
it’s done with the^ latter.)
[d]^ for (each vertex v
in^ the
graph)
if (v has not been
visited)
increment the
count
of^ connected
components
perform DFS on
v,^ thereby
marking
all^ vertices
in^ its
connected
component
as^ having
been visited
}} This algorithm requires
that you^ don’t "unmark"
the^ marked
vertices
between calls to DFS. [5]^ [a]^
[b]^
practice.sol
[c]^
[d]^
[a]^ If^ the
find operations are done first, then the find operations take O(1)^ time^ each because every item is the root of its own tree.
No
item^ has^ a parent, so finding the set an item is in takes a fixed number
of^ operations. Union operations always take O(1) time.
Hence, a sequence of n
operations
with all the finds before the unions takes O(n) time. [b]^ This^ question
requires amortized analysis.
Find operations can be
expensive,
but an expensive find operation is balanced out by lots of^ cheap
union operations.
The accounting is as follows.
Union operations always take O(1) time, so let’s say they have an actual
cost of $1.
Assign each union operation an amortized cost of
$2,^ so
every
union operation puts $1 in the bank. Each^ union operation creates a new child.
(Some node that was not
a^ child
of^ any other node before is a child now.)
When all the
union operations are done, there is $1 in the bank for every child, or^ in other
words, for every node with a depth of one or greater. Let’s say^ that a find(u) operation costs $1 if u is a root.
For any
other node,
the find operation costs an additional $1 for each parent pointer
the^ find operation traverses.
So the actual cost is
d),^ where d is the depth of u. Assign
each find operation an amortized cost of $2.
This covers
the^ case
where u is a root or a child of a root.
For each additional
parent
pointer traversed, $1 is withdrawn from the bank to pay for it.Fortunately,
path compression changes the parent pointers of all the nodes we^ pay
$1 to traverse, so these nodes become children of the root. All of^ the traversed nodes whose depths are 2 or greater move up,^ so
their
depths are now 1.
We will never have to pay to traverse
these nodes
again.
Say that a node is
a^ grandchild
if^ its
depth
is^2 or^ greater.
Every
time find(u) visits
a^ grandchild,
$1^ is
withdrawn
from the^ bank, but
the grandchild is
no^ longer
a^ grandchild.
So^ the^ maximum
number
of
dollars that can ever
be^ withdrawn
from the^ bank^ is^ the
number
of
grandchildren.
But we^ initially
put^ $1^ in the^ bank^ for^ every
child,
and every grandchild
is^ a child,
so^ the
bank balance
will never
drop
below zero.
Therefore,
the^ amortization
works
out.
Union and find operations
both have amortized
costs
of^ $2,
so^ any
sequence of n operations
where
all^ the^ unions
are^ done^ first takes
O(n) time. [7]^ [a]^ insert 4, 2, 1, 3,
and^ 6 in^ that^ order.
[b]^ insert 4, 5, 6, 1,
3,^ and
2 in that order.
[a]^ If you need inexact
matches.
For example,
if^ you
want to^ find
the
item less than or
equal
to^5 that’s
closest
to^ 5.
Hash
tables
can
only do exact matches.
(If exact
matches
are^ all^ you
need,
however,
hash tables are faster.) [b]^ If each single operation
absolutely
must run^ in^ O(log
n)^ time.
If most operations
are^ find()s,
and^ the^ data
access
patterns
are
uniformly random.
trees
are^ faster
for^ these operations
because they don’t
restructure
the^ tree. But splay
trees
do^ better
if a small proportion
of^ the
items
are^ targets
of^ most
of^ the
finds.)
[c]^ If memory use is the
primary
consideration
(especially
if^ a
tree holding all the
items
won’t
fit^ in^ memory).
[d]^ None. find() and
remove()
on^ a heap take worst-case
Theta(n)
time,
and they’re more complicated
than in^ an
unordered
array.
insert()
on a heap takes worst-case
Theta(log
n)^ time,
versus
Theta(1)
for^ an
unordered array. [11]^
[a]^
[b]^
(Note that two^ nodes are^ different
than in^ [a].)
Radix sort takes b/log
r^ passes,
so^ the
overall
running
time of^ radix
sort is
n +^ r t =^ b (ln 2) -----
ln^ r
To find the value of r
that minimizes
t,^ set
dt/dr
to^ zero.
dt^
ln^ r^
-^ (n^ +^ r)/r
-- = b (ln 2) ----------------
dr^
(ln^ r)^
Therefore, ln r = (n +
r)/r.
Given
that n^ =^
with^ a^ calculator
and
some trial-and-error you
can^ determine
that r^ =^ 128 is
the^ optimal
radix.