doc

advertisement
Priority Queues (Heaps)
Binary Heaps (continued)
Although a binary heap is designed only so that the minimum (maximum) can be easily
found, it is sometimes important to know where elements are in a priority queue.
In order to achieve this, some other technique, such as hashing, must be used in parallel to
looking inside the priority queue.
If we assume that a method (such as hashing) is available that knows the position of
every other element, then other useful operations are possible.
Increase the priority of an element in the priority queue.
This operation lowers the value of an element.
Starting in the position where the value was changed, the percolate up procedure should
be done to ensure that the heap-order property is not violated.
Example:
13
13
21
16
5
5
16
13
16
5
24
65
31
26
19
68
32
21
65
31
26
19
68
32
21
65
31
26
19
68
32
Decrease the priority of an element in the priority queue.
This operation increases the value of an element.
Starting in the position where the value was changed, the percolate down procedure
should be done to ensure that the heap order property is not violated.
Example:
13
13
13
27
21
16
24
65
31
26
32
19
24
68
16
27
65
31
26
32
19
24
68
16
26
65
31
27
32
19
68
Remove an element from the priority queue.
This operation gives an element the highest priority using the increase priority operation
It then uses DeleteMin to remove the element.
An implementation of a priority queue of this nature need to administer both the binary
heap and the hash table.
A typical heap data structure declaration using hashing:
const int HEAP_SIZE = 16;
const int AVAILABLE = -1;
struct HashPointer
{
Object key;
int location;
};
struct BinaryHeap
{
int elementCount;
Object a[HEAP_SIZE];
HashPointer h[HEAP_SIZE];
};
A simple hash function for a heap of integers
Input:
x, the key to hash
action, INSERT, LOOKUP or DELETE
h, the address of the hash table
Output:
the hashed value of the key.
Hash(x, action, h)
{
v = x mod HEAP_SIZE
if action == INSERT
while h[v].key != AVAILABLE
v = (v + 1) mod HEAP_SIZE
else
while h[v] != x
v = (v + 1) mod HEAP_SIZE
if action == DELETE
h[v].key = AVAILABLE
return v
}
Insert a new value into the heap (assumes the heap is not full)
Input:
x, the value to insert
a, the address of the heap
h, the address of the hash table
Output:
a, the modified heap
h, the modified hash table.
Insert(x, a, h)
{
elementCount++
i = elementCount
while i > 1 and x < a[i/2]
a[i] = a[i/2]
v = Hash(a[i/2], LOOKUP, h)
h[v].location = i
i = i/2
a[i] = x
v = Hash(x, INSERT, h)
h[v].key = x
h[v].location = i
}
Delete the minimum element from the heap (assumes the heap is not empty)
Input:
a, the address of the heap
h, the address of the hash table
Output:
x, the minimum element
a, the modified heap
h, the modified hash table.
DeleteMin(x, a, h)
{
x = a[1]
Hash(x, DELETE, h)
a[1] = a[elementCount]
elementCount-temp = a[elementCount]
i = 1
while i*2 <= elementCount
child = i*2
if child != elementCount and a[child+1] < a[child]
child++
if a[child] < temp
a[i] = a[child]
v = Hash(a[child], LOOKUP, h)
h[v].location = i
else
break
i = child
a[i] = temp
v = Hash(temp, LOOKUP, h)
h[v].location = i
}
Increase the priority of an element in the priority queue (may require a percolate up to restore
the heap order property)
Input:
x, the value to insert
d, the amount of the increase
a, the address of the heap
h, the address of the hash table
Output:
a, the modified heap
h, the modified hash table.
IncreasePriority(x, d, a, h)
{
v = Hash(x, DELETE, h)
i = h[v].location
a[i] = a[i] - d
x = a[i]
while i > 1 and x < a[i/2]
a[i] = a[i/2]
v = Hash(a[i/2], LOOKUP, h)
h[v].location = i
i = i/2
a[i] = x
v = Hash(x, INSERT, h)
h[v].key = x
h[v].location = i
}
Decrease the priority of an element in the priority queue (may require a percolate down to
restore the heap order property)
Input:
x, the value to insert
d, the amount of the increase
a, the address of the heap
h, the address of the hash table
Output:
a, the modified heap
h, the modified hash table.
DecreasePriority(x, d, a, h)
{
v = Hash(x, DELETE, h)
i = h[v].location
a[i] = a[i] + d
temp = a[i]
while i*2 <= elementCount
child = i*2
if child != elementCount and a[child+1] < a[child]
child++
if a[child] < temp
a[i] = a[child]
v = Hash(a[child], LOOKUP, h)
h[v].location = i
else
break
i = child
a[i] = temp
v = Hash(temp, LOOKUP, h)
h[v].location = i
}
Remove an element from the priority queue
Input:
x, the value to remove
a, the address of the heap
h, the address of the hash table
Output:
a, the modified heap
h, the modified hash table.
Remove(x, a, h)
{
IncreasePriority(x, LOW_VALUE, a, h)
DeleteMin(y, a, h)
}
Download