Sie sind auf Seite 1von 48

Associative Tables

• An associative table is just like an array, except that the


index is not restricted to lie between two pre-specified
bounds.
• T[“Asif”]is as legitimate as T[1].
• The easiest way to implement a table is with a list
type table-list = table-node
type table-node=record
index: index-type
value: information
next:  table-node
• This implementation is very inefficient due to longer delay
in searching
Associative Tables
• A sequence of n accesses requires a time in  (n2)
• If up to m distinct indexes are used in those n accesses, mn,
and if each request is equally likely to access any of those
indexes, the average-case performance of this implementation
is  (mn).
• Balanced trees can be used to reduce this time to O(n log m)
in the worst case. This is better, but still not good enough for
one of the main applications for associative tables, namely
compilers.
• Most compilers used a technique known as hash coding, or
simply hashing.
Hashing
• A hash function is a function h: U {0, 1, 2, …., N-1}. This function
should efficiently disperse all the probable indexes: h(x) should be
different from h(y) for most of the pairs xy likely to be used
simultaneously.
• When xy but h(x) = h(y), then there is a collision between x and y. It is
intolerable because a collision probability can not be neglected.
• In hashing or chaining, each entry of array A[0..N-1] is of type table-list:
A[i] contains the list of all indexes that hash to value i, together with their
relevant information illustrates the situation after the following four
requests to associative table T.
T[“Laurel”] 3
T[“Chaplin”] 1
T[“Hardy”] 4
T[“Keaton”] 1
• In this example, N=6, h(“Keaton”)=1, h(“Laurel”)=h(Hardy”)=2 and
h(“Chaplin”)=4.
Hashing
• The load factor of the table is m/N, where m is the number of
distinct indexes used in the table and N is the size of the array
used to implement it.
• The table takes space in (N+m) and the average length of the
lists is equal to the load factor. Thus increasing N reduces the
average list length but increases the space occupied by the
table.
• If the load factor is kept between ½ and 1, the table occupies a
space in (m), which is optimal up to a small constant factor,
and the average list length is less than 1, which is likely to
imply efficient access to the table.
• The load factor is allowed to be smaller that ½ when the
number of identifiers is small.
ILLUSTRATION OF HASHING

0
1 Keaton 1

2 Laurel 3 Hardy 4

3
4 Chaplin 1

5
Hashing
• Whenever more than N different identifiers are encountered,
causing the load factor to exceed 1, it is time to double the
size of the array used to implement the hash table. At that
point, the hash function must be changed to double its range
and every entry already in the table must be rehashed to its
new position in a list of the larger array.
• Rehashing is expensive.
• Rehashing is repeated each time the load factor exceeds 1;
after rehashing the load factor drops back to ½
T
0
U
(Universe of keys) h(K1)
K1 h(K4)
K
K4 h(K2)=h(K5)
(actual K5
keys) K2
K3 h(K3)

m-1

Figure: Using a hash function h to map keys to


hash-table slots. Keys K2 and K5 to the same slot, so
they collide.
T

U K1 K4
(Universe of keys)

K1
K
K4 K5 K2 K7
(actual K5
keys) K7
K3 K3
K2
K8 K8 K6
K6

Figure: Collision resolution by chaining. Each-table slot T[j]


contains a linked list of all the keys whose hash value is j. For
example, h(k1)=h(k4) and h(k5)=h(k2)=h(k7).
Heaps
• A heap is a special kind of rooted tree that can be
implemented efficiently in an array without any explicit
pointers.
• It can be used for heap sort and the efficient representation of
certain dynamic priority lists, such as the event list in a
simulation or the list of tasks to be scheduled by an operating
system.
• A binary tree is essentially complete if each internal node,
with the possible exception of one special node, has exactly
two children.
• The special node if there is one, is situated on level 1; it has a
left child but no right child.
• Either all the leaves are on level 0, or else they are on levels 0
and 1, and no leaf on level 1 is to the left of an internal nodes
at the same level.
Heaps
• An essentially complete tree is one where the internal nodes
are pushed up the tree as high as possible
• Figure illustrates an essentially complete binary tree
containing 10 nodes. The five internal nodes occupy level 3
(the root), level 2, and the left side of level 1; the five leaves
fill the right side of level 1 and then continue at the left of
level 0.
• If an essentially complete binary tree has height k, then there
is one node (the root) on level k, there are two nodes on level
k-1 and so on; there are 2k-1 nodes on level 1, and at least 1
and not more than 2k on level 0.
• A heap is an essentially complete binary tree, each of whose
nodes includes an element of information called the value of
the node, and which has the property that the value of each
internal node is greater than or equal to the values of its
children.
An essentially complete binary tree
T[1]

T[3]

T[2]

T[5] T[6] T[7]


T[4]

T[8] T[9] T[10]


A heap
10

7 9

4 7 5 2

2 1 6

Figure shows an example of a heap with 10 nodes.


Heaps
• Now we have marked each node with its value.
• This same heap can be represented by the following array

10 7 9 4 7 5 2 2 1 6
• The crucial characteristic of this data structure is that the heap
property can be restored efficiently if the value of a node is modified.
• If the value of a node increases to the extent that it becomes greater
than the value of its parent, it suffices to exchange these two values,
and then to continue the same process upwards in the tree if
necessary until the heap property is restored.
• The modified value is percolated up to its new position in the heap
• This operation is often called sifting up
• If the value 1 in Figure is modified so that it becomes 8, we can
restore the heap property by exchanging the 8 with its parent 4, and
then exchanging it again with its new parent 7.
The heap, after percolating 8 to its place
10

8 9

7 7 5 2

2 4 6
Heaps
• If on the contrary the value of a node is decreased so that it
becomes less than the value of at least one of its children, it
suffices to exchange the modified value with the larger of the
values in the children, and then to continue this process
downwards in the tree if necessary until the heap property is
restored.
• The modified value has been sifted down to its new position.
9

8 5
The heap, after sifting 3 (originally 10)
down to its place
7 7 3 2

2 4 6
Heaps
• The following procedures describe more formally the basic
processes for manipulating a heap.

Procedure alter-heap (T[1..n], i, v)


{T[1..n] is a heap. The value of T[i] is set to v and
the heap property is re-established. Suppose that
1 i  n.}
xT[i]
T[i] v
if v < x then sift-down(T,i)
else percolate (T,i)
Procedure sift-down (T[1…n], i)
{This procedure sifts node i down so as to re-establish the
heap property in T[1..n]. Suppose that T would be a heap if
T[i] were sufficiently large and that 1 i  n.}
ki
repeat
jk
{find the larger child of node j}
if 2j  n and T[2j]> T[k] then k  2j
if 2j < n and T[2j+1]> T[k] then k  2j+1
exchange T[j] and T[k]
{if j=k, then the node has arrived at its final position}
until j=k
Procedure percolate (T[1…n], i)
{This procedure percolate node i so as to re-establish the heap
property in T[1..n]. Suppose that T would be a heap if T[i]
were sufficiently small and that 1 i  n. The parameter n is
not used here}
ki
repeat
jk
if j > 1 and T[j  2]< T[k] then k  j 2
exchange T[j] and T[k]
{if j=k, then the node has arrived at its final
position}
until j=k
Heaps
• Heap is an ideal data structure for finding the largest element
of a set, removing it, adding a new node, or modifying a node.
These are exactly the operations we need to implement
dynamic priority lists efficiently. The value of a node gives
the priority of the corresponding event, the event with highest
priority is always found at the root of the heap, and the
priority of an event can be changed dynamically at any time.
This is particularly useful in computer simulations and in the
design of schedulers for an operating system.
• Some typical procedures are illustrated below.
function find-max (T[1..n])
{Returns the larges element of the heap T[1..n]}
return T[1]

Procedure delete-max (T[1…n])


{Removes the largest element of the heap T[1..n] and
restores the heap property in T[1..n – 1]}
T[1]  T[n]
sift-down( T[1..n – 1], 1)
Procedure insert node (T[1…n], v)
{Adds an element whose value is v to the heap T[1..n]
and restores the heap property in T[1..n + 1]}
T[n+1]  v
percolate(T[1..n + 1], n+1)

It remains to be seen how to create a heap starting form an array


T[1..n] of elements in an undefined order. The obvious solution
is to start with an empty heap and to add elements one by one.
Procedure slow-make-heap (T[1…n])
{This procedure makes the array (T[1..n]) into
a heap - an inefficient method}
for i  2 to n do percolate (T[1..i],i)
Heaps
• There exists a cleverer algorithm for making a heap. Suppose, for
example, that our starting point is the following array represented by the
tree in Figure.

1 6 9 2 7 5 2 7 4 10

1
The starting situation
9
6

2 7 5 2

7 4 10
Heaps
• We first make each of the subtrees whose roots are at level 1
into a heap, this is done by sifting down these tools, as
illustrated in Figure.

10
7 5 2

2 4 7

The level 1 subtrees are made into heaps


Heaps
This figure shows the process for the left subtree. The other subtree at level 2
is already a heap. This results in an essentially complete binary tree
corresponding to the array.

1 10 9 7 7 5 2 2 4 6

6 10 10

7 10 7 6 7 7

2 4 7 2 4 7 2 4 6

One level 2 subtree is made into a heap (the other already is a heap)
It only remains to sift down its root to obtain the desired
heap. This process thus goes as follows:

10 1 9 7 7 5 2 2 4 6
10 7 9 1 7 5 2 2 4 6
10 7 9 4 7 5 2 2 1 6

10

7 9

4 7 5 2

2 1 6
Formal description of the algorithm is as under:-
Procedure make-heap(T[1..n])
{This procedure makes the array T[1..n] into a
heap}
for i [n/2 ]downto 1 do sift-down(T,i)
Procedure heapsort (T[1..n])
{T is an array to be sorted}
make-heap(T)
for i  n downto 2 do
exchange T[1] and T[i]
sift-down(T[1..i – 1], 1)
• There is no good way of searching for a particular item in a
heap.
• There is no efficient way of merging two heaps. The best
way we can do is to put the contents of the two heaps side
by side in an array, and then call procedure make-heap on
the combined array.
• In any kind of heap searching for a particular item is
inefficient.
Heap viewed as a binary tree
16

14 10

8 7 9 3

2 4 1

16 14 10 8 7 9 3 2 4 1

Heap viewed as an array


Construct the heap using the array
A=(16, 4, 10, 14, 7, 9, 3, 2, 8, 1)
16

4 10
The initial configuration
14 7 9 3

2 8 1 16

14 10

8 7 9 3
Maintaining heap property
2 4 1
Making a heap
A 4 1 3 2 16 9 10 14 8 7
1 2 3 4 5 6 7 8 9 10
T[1]
4

T[2]
1 3 T[3]

T[6]
T[4]
2 T[5] 16 9 10 T[7]

T[8]
14 8 7 T[10] Procedure make-heap (T[1..10])
For i5 to 1 do sift-down(T,i)
T[9]
a. i = 5, Sift-down (T, 5); both if = false  no exchange
4 1 3 2 16 9 10 14 8 7
b. i = 4, Sift-down (T, 4); first if = true  exchange T[4] & T[8]
4 1 3 2 16 9 10 14 8 7
c. i = 3, Sift-down (T, 3); first & 2nd if = true  exchange T[3]
& T[7]
4 1 3 14 16 9 10 2 8 7
d. i = 2, Sift-down (T, 2); 2nd if = true  exchange T[2] & T[5]
4 1 10 14 16 9 3 2 8 7
e. i = 1, Sift-down (T, 1); first if = true  exchange T[1] & T[2]
Repeat ……
4 16 10 14 7 9 3 2 8 1
16
Final heap after all operations
14 10

8 7 9 3

2 4 1

1
A= 16 14 10 8 7 9 3 2 4 1 16
3
2 14
10
for in down 2 do
5 7
exchange T(1) and T(i) 4
8 6
7 9 3
Sift-down(T[..i-1],1)
9
8 10
2 4 1 Make-heap (T)
i = 10, exchange T[1] & T[10] and sift-down (T[1..9],1)
14 8 10 4 7 9 3 2 1 16
1 2 3 4 5 6 7 8 9 10
i = 9, exchange T[1] & T[9] and sift-down (T[1..8],1)
10 8 9 4 7 1 3 2 14 16
1 2 3 4 5 6 7 8 9 10
i = 8, exchange T[1] & T[8] and sift-down (T[1..7],1)
9 8 3 4 7 1 2 10 14 16
1 2 3 4 5 6 7 8 9 10
i = 7, exchange T[1] & T[7] and sift-down (T[1..6],1)
8 7 3 4 2 1 9 10 14 16
1 2 3 4 5 6 7 8 9 10
i = 6, exchange T[1] & T[6] and sift-down (T[1..5],1)
7 4 3 1 2 8 9 10 14 16
1 2 3 4 5 6 7 8 9 10
i = 5, exchange T[1] & T[5] and sift-down (T[1..4],1)
i = 5, exchange T[1] & T[5] and sift-down (T[1..4],1)
4 2 3 1 7 8 9 10 14 16
1 2 3 4 5 6 7 8 9 10
i = 4, exchange T[1] & T[4] and sift-down (T[1..3],1)
1 2 3 4 7 8 9 10 14 16
1 2 3 4 5 6 7 8 9 10
i = 3, exchange T[1] & T[3] and sift-down (T[1..2],1)

2 1 3 4 7 8 9 10 14 16
1 2 3 4 5 6 7 8 9 10
i = 2, exchange T[1] & T[2] and sift-down (T[1..1],1)

1 2 3 4 7 8 9 10 14 16
1 2 3 4 5 6 7 8 9 10
End of Sorting
Sorted heap
1

2 3

4 7 8 9

10 14 16
B0 B1 B2 B3 B4

Binomial trees B0 to B4
max

3 25 23

12 9 14 20

1 5 17

A binomial heap containing 11 items


15 12 15
+

1 9 4 8 1 9
12

6 3 6 4 8

Linking two B2’s to make a B3


7 12 9 13 10

3 1 11 merged with 2 5 8

6 4
yields 9 13 12

2 7 1 11 10

3 6 5 8

Merging two binomial heaps


4
head [H1] 12 7 15

25 28 33

41

BINOMIAL-HEAP MERGE

head [H2] 18 3 6

8 29 10 44
37

30 23 22 48 31 17

45 32 24 50

55
head [H] 12 3 15 6

18 37 28 33 8 29 10 44
7

25 41 30 23 22 48 31 17

45 32 24 50

55
head [H] 12 3 6

18 15 37 8 29 10 44
7

28 33 25 30 23 22 48 31 17

41 45 32 24 50

55
head [H] 37 10 1

41 28 13 6 16 12 25

77 8 14 29 26 23 18

11 17 38 42

27

The node with value 1 to be deleted


(b) head [H] 37 10 1

41 28 13 6 16 12 25

77 8 14 29 26 23 18

11 17 38 42

Separated into two heaps 27


head [H] 37 10 head [H] 25 12 16 6

41 28 13 18 26 23 8 14 29

77 42 11 17 38

27

Node with value 1 has been deleted, two heaps H & H

head [H] 25 12 6

37 18 10 8 14 29

41 16 28 13 11 17 38

26 23 77 27

42
Merging heaps H & H
head [H] 25 12 6

37 10 8 14 29
18

41 16 28 13 11 17 38

y 7 23 77 27

42

Node y value decreased from 26 to 7


head [H] 25 12 6

37 10 8 14 29
18

41 7 28 13 11 17 38

16 23 77 27

42
head [H] 25 12 6

37 8 14 29
18 7

41 10 28 13 11 17 38

16 23 77 27

42
head [H] 10 47 8 12 4

61 26 11 13 14 15 24

75 19 22 36 27 31 16

30 29 44 43

50
head [H] 10 47 8 12 4

61 26 11 13 14 15 24

75 19 22 36 27 31 16

30 29 44 43

50

Quiz # 3. Delete node with value 26 and readjust the binomial heap.

Das könnte Ihnen auch gefallen