Title: Tirgul 11
1Tirgul 11
- Solutions for questions from T2, T3
- DFS BFS - reminder
- Some Hashing
Reminder dont forget to run dast/bin/testEx3.cs
h on your jar file before submitting ex3!!!
2T2 Question 3
- Q Prove that there is no comparison-based sort
whose running time is linear for at least half of
the n! inputs of length n. - A A comparison based sort can be described by a
decision tree - Each node is a comparison
- Each edge is an outcome of a comparison
- The running time is the depth of the correct leaf.
3T2 Question 3
- A tree of height h has less than 2h1 nodes
- If there are n!/2 leaves at depth cn, then
- 2cn1 n!/2 ? cn 1 log(n!) - 1
- ? n ?(n logn) ? contradiction!
- What about 1/n of the input? And 1/2n of the
input? - 2cn1 n!/n ? cn 1 log((n-1)!) ?(n logn)
- 2cn1 n!/2n ? cn 1 log(n!) - n ?(n
logn) - ? Both impossible as well
4T3 Question 1
- Q Suppose that another data structure contains a
pointer to a node y in a binary search tree, and
suppose that ys predecessor z is deleted from
the tree by the procedure TREE-DELETE. What
problem can arise? How can TREE-DELETE be
rewritten to solve the problem?
delete
z
y
external reference
5T3 Question 1
- If z has two children, then the deletion of z
consists of - Replacing the contents of z with the contents of
the successor of z - Deleting the successor of z
- In this case, we will delete the node where y
used to be. - So the reference to y will become invalid, even
though we did not delete y itself
y
?
external reference
6T3 Question 1
- Solution instead of copying the contents of y
into z, place the node y in the tree where z used
to be, after deleting it - yz.successor
- make y.right the child of y.parent instead of y
- connect y to zs parent and children instead of z
y
external reference
7T3 Question 5
- An in-order tree walk can be implemented by
finding the minimum element and then making n-1
calls to TREE-SUCCESSOR - Q How many times at most do we pass through each
edge?
8T3 Question 5
- TREE-SUCCESSOR(x)
- if x.rightnull
- yx.parent
- while y!null xy.right
- xy
- yy.parent
- else
- yx.right
- while y.left!null
- yy.left
- return y
going up (1)
going up (2)
going down (3)
going down (4)
9T3 Question 5
- Right edges
- A right edge n?n.right is passed downwards only
at (3), which happens when we call
TREE-SUCCESSOR(n) - Since we call TREE-SUCCESSOR once for each node,
we go down each right edge once, at most - Left edges
- After we pass a left edge n?n.left (at (1) or
(2)), TREE-SUCCESSOR returns n - Since TREE-SUCCESSOR returns each node once, we
go up each left edge once, at most - For each time we go down an edge, we have to go
back up that edge, and vice versa - Therefore, we pass each edge at most twice
- In-order walk takes O(n) steps
10T4 Question 2
- Q You are in a square maze of n?n cells and
youve got loads of coins in your pocket. How do
you get out?
- A The maze is a graph where
- Each cell is a node
- Each passage between cells is an edge
- Solve the maze by running DFS until the exit is
found
11DFS - Reminder
DFS-VISIT(u) u.colorgray u.dtime for
each v?adju if v.colorwhite
v.prevu DFS-VISIT(v) u.colorblack
u.ftime
DFS(G) for each u?VG u.colorwhite
u.prevnil time0 for each u?VG if
u.colorwhite DFS-VISIT(u)
12BFS - Reminder
BFS(G,s) for each u?VG u.dist8
s.dist0 Q.enqueue(s) while Q not empty
uQ.dequeue() for each v?adju if
v.dist8 v.distu.dist1
v.prevu Q.enqueue(v)
13T4 Question 2
- A white node is a cell without any coins
- A gray node is a cell with a coin lying with its
head side up - A black node is a cell with a coin lying with its
tail side up - An edge connecting a node to its parent is marked
by a coin - When visiting a cell, we color it gray
- If it has a white cell adjacent to it visit it
- If there are no such cells,
- Color the cell black by flipping the coin
- backtrack by going to the cell marked as parent
14T4 Question 2
- Each node has one parent
- When backtracking, the parent will be the only
adjacent gray cell that has a coin leading to
it
- Can we solve it using BFS?
- Answer No! In DFS we go between adjacent cells
in BFS, the nodes are in a queue, so the next
cell could be anywhere
15Dynamic Hash Tables
- Since performance depends on the load factor, we
would like to expand the table when the load
factor is too high - Expansion involves allocating a new table and
rehashing the keys into it from the old table - Most insertions would be O(1), but some
insertions will cause the table to expand, which
would take O(n) - So, table operations take O(n) in the worst case,
but what is the average time for a table
operation in the worst case? What is the worst
case for n operations? We use amortized analysis
to answer these questions
16Example - Stack with multi-pop
- As a first example we analyze the performance of
a stack with one additional operation -
multipop(k)- that pops the top k elements of the
stack. - Since multipop can take O(n) time in the
worst-case, we might conclude that n stack
operations can take O(n2) in the worst case. - We will analyze this simple D.S. using two
methods - The aggregate method
- The accounting method
- and see that the average time per operation is
still O(1).
17The aggregate method
- In this method we find T(n), the total time to
perform n operations in the worst-case. The
amortized cost of each operation is then defined
as T(n)/n. - In our stack example, T(n) O(n) If we
performed a total of k push operations, then the
total time for the pop and multipop operations is
also at most k (the number of elements we can pop
is at most the number of elements we pushed).
Since k is at most n, then T(n)O(n). - Thus the amortized cost for all operations is
O(1).
18The accounting method
- In this method, we receive money for each
operation. - We pay for the actual cost of the operation
- With whats left we may pay for future
operations. - The total cost for n operations is the total
money we got, since with it we covered the
entire actual cost. - The amortized cost of each operation is the money
we got for this operation. - In our stack example, we define the following
- The amortized cost (the money we get) for a
push operation is 2, and for the pop and multipop
operation is 0. - When pushing an item, we pay 2 1 goes to the
push operation, and 1 is left to its credit this
will pay for its pop or multipop.
19The accounting method (continued)
Operation
Actual cost
Average (amortized) cost
push
1
2
pop
1
0
multipop
k
0
- So we see that the average cost of each operation
is constant (in contrast to the actual cost). In
other words, since the total payment is at most
2n, the total time is at most O(n), and the
average time is per operation is O(1).
20Dynamic Tables
- A Dynamic table is an array that expands
dynamically when it becomes overloaded, to fit
itself to a variable demand. What is it good for? - Javas Vector
- Heaps
- Hash tables
- In a dynamic table, besides the regular insert
and delete, there is also expansion when the
table is overloaded and we want to insert a new
element.
21Expansion
- Consider the following expansion scheme
- Table starts with a size of 1.
- Upon an insert, if the table is full, create a
table twice the old size and copy the old table
to the beginning of the new one. - Actual cost 1 for regular insertion, size(T) for
expansion.
22Expansion - Aggregate
- Expansion doubles the table size
- Therefore, for every i, after inserting the 2i1
item, a new table of size 2i1 will be allocated
and 2i values will be copied - So, the number of operations required for n
insertions is - Therefore, the amortized cost of each insertion
is O(1).
23Expansion - Accounting
- Amortized cost, the accounting method
- Suppose we pay 3 for every regular insertion 1
for the actual cost, and 2 remains as credit for
this element. - How do we pay for an expansion? Suppose the table
is doubled from size x to 2x. Then we have x/2
elements that didnt pay for an expansion yet
(have credit of 2). Thus each one of them pays
for itself and for one other element out of the
x/2 with credit 0.
24Expansion Hash Tables
- When the load factor is too high, we would like
to expand the table - Since the hash codes depend on the table size, we
need to rehash compute the new hash code for
every item in the old table and use it to insert
it to the new table - If the maximal load factor is constant, the
amortized cost of insertion remains O(1)