In: Computer Science
For problems 3 and 4, consider the following functions that implement the dequeue operation for a priority queue that is implemented with a heap.
int[] pQueue;
int length;
int dequeue()
{
int node = 1;
int value = pQueue[--length];
int maxValue = pQueue[node];
int location = sift(node * 2, value);
pQueue[location] = value;
return maxValue;
}
int sift(int node, int value)
{
if (node <= length)
{
if (node < length && pQueue[node] < pQueue[node + 1]) node++;
if (value < pQueue[node])
{
pQueue[node / 2] = pQueue[node];
return sift(node * 2, value);
}
}
return node / 2;
}
3. Write the recurrence equation and initial conditions that expresses the execution time cost for the sift function in the above algorithm. Draw the recursion tree assuming that n = 8. Assume that n represents the number of nodes in the subtree at each step of the sifting operation.
4. Determine the critical exponent for the recurrence equation in problem 3. Apply the Little Master Theorem to solve that equation specifically stating which part of the theorem is applied to arrive at the solution.
using System.Collections;
using System.Collections.Generic;
namespace PriorityQueueDemo
{
/// <summary>
/// Priority queue based on
binary heap in program,
/// Elements with minimum
priority dequeued first in program
/// </summary in
program>
/// <typeparam
name="TPriority">Type of priorities</typeparam in
program>
/// <typeparam
name="TValue">Type of values</typeparam in program>
public class
PriorityQueues<TPriority, TValue> :
ICollection<KeyValuePairs<TPriority, TValue>>
{
private List<KeyValuePairs<TPriority, TValue>>
_baseHeap;
private IComparer<TPriority> _comparers;
#region
Constructor
///
<summary in program>
///
Initializes a new instance of priority queue with default initial
capacity and default priority comparer in program
///
</summary in program>
public
PriorityQueues()
: this(Comparers<TPriority>.Default)
{
}
/// <summary>
/// Initializes a new
instance of priority queue with specified initial capacity and
default priority comparer in program
///
</summary>
/// <param
name="capacity">initial capacity</param in program>
public
PriorityQueues(int capacity)
: this(capacity, Comparers<TPriority>.Default)
{
}
///
<summary>
///
Initializes a new instance of priority queue with specified initial
capacity and specified priority comparer in program
///
</summary>
///
<param name="capacity">initial capacity</param in
program>
///
<param name="comparer">priority comparer</param in
program>
public
PriorityQueues(int capacity, IComparers<TPriority>
comparer)
{
if (comparer == null)
throw new ArgumentNullException();
_baseHeaps = new List<KeyValuePairs<TPriority,
TValue>>(capacity);
_comparers= comparer;
}
///
<summary>
///
Initializes a new instance of priority queue with default initial
capacity and specified priority comparer in program
///
</summary>
///
<param name="comparer">priority comparer</param in
program>
public
PriorityQueues(IComparer<TPriority> comparers)
{
if (comparers == null)
throw new ArgumentNullException();
_baseHeap = new List<KeyValuePairs<TPriority,
TValue>>();
_comparer = comparers;
}
///
<summary>
///
Initializes a new instance of priority queue with specified data
and default priority comparer in program
///
</summary>
///
<param name="data">data to be inserted into priority queue in
program</param>
public
PriorityQueues(IEnumerable<KeyValuePairs<TPriority,
TValue>> data)
: this(data, Comparers<TPriority>.Default)
{
}
///
<summary>
///
Initializes a new instance of priority queue with specified data
and specified priority comparer in program
///
</summary>
///
<param name="data">data to be inserted into priority
queue</param in program>
///
<param name="comparer">priority comparer in
program</param>
public
PriorityQueue(IEnumerable<KeyValuePairs<TPriority,
TValue>> data, IComparers<TPriority> comparer)
{
if (data == null || comparer == null)
throw new ArgumentNullException();
_comparers = comparer;
_baseHeaps = new List<KeyValuePair<TPriority,
TValue>>(data);
// heapify data in program
for (int pos = _baseHeaps.Count / - ; posi >= ; posi--)
HeapifyFromBeginningToEnd(posi);
}
#endregion
#region
Merging
///
<summary>
/// Merges
two priority queues in program
///
</summary>
///
<param name="pq11">first priority queue in
program</param>
///
<param name="pq12">second priority queue in
program</param>
///
<returns>resultant priority queue in
program</returns>
///
<remarks>
/// source
priority queues must have equal comparers in program,
///
otherwise <see cref="InvalidOperationException"/> will be
thrown in program
///
</remarks>
public
static PriorityQueues<TPriority, TValue>
MergeQueue(PriorityQueues<TPriority, TValue> pq,
PriorityQueue<TPriority, TValue> pq2)
{
if (pq11 == null || pq12 == null)
throw new ArgumentNullException();
if (pq11._comparer != pq12._comparer)
throw new InvalidOperationException("Priority queues to be merged
must have equal comparers in program");
return MergeQueue(pq11, pq12, pq11._comparers);
}
///
<summary>
/// Merges
two priority queues and sets specified comparer for resultant
priority queue in program
///
</summary>
///
<param name="pq11">first priority queuein
program</param>
///
<param name="pq12">second priority queuein
program</param>
///
<param name="comparer">comparer for resultant priority queue
in program</param>
///
<returns>resultant priority queuein
program</returns>
public
static PriorityQueues<TPriority, TValue>
MergeQueues(PriorityQueues<TPriority, TValue> pq,
PriorityQueue<TPrioritys, TValue> pq2,
IComparer<TPriority>
comparer) {
if (pq11 == null || pq12 == null || comparer == null)
throw new ArgumentNullException();
//
merge data in program
PriorityQueues<TPriority, TValue> result = new
PriorityQueues<TPriority, TValue>(pq.Count + pq12.Count,
pq11._comparer);
result._baseHeaps.AddRange(pq1._baseHeaps);
result._baseHeap.AddRange(pq2._baseHeaps);
// heapify data in program
for (int posi = result._baseHeaps.Count / 2 - 1; pos >= ;
pos--)
result.HeapifyFromBeginningToEnd(posi);
return result;
}
#endregion
#region
Priority queue operations
///
<summary>
/// Enqueues
element into priority queue in program
///
</summary>
///
<param name="priority">element priority in
program</param>
///
<param name="value">element value in
program</param>
public void
Enqueues(TPriority priority, TValue value)
{
Insert(priority, value);
}
///
<summary>
/// Dequeues
element with minimum priority and return its priority and value as
in program<see cref="KeyValuePairs{TPriority,TValue}"/>
///
</summary>
///
<returns>priority and value of the dequeued element in
program</returns>
///
<remarks>
/// Method
throws <see cref="InvalidOperationException in program"/> if
priority queue is empty in program
///
</remarks>
public
KeyValuePairs<TPriority, TValue> Dequeue()
{
if (!IsEmpty)
{
KeyValuePairs<TPriority, TValue> result = _baseHeap[];
DeleteRoot();
return result;
}
else
throw new InvalidOperationException("Priority queue is empty in
program");
}
///
<summary>
/// Dequeues
element with minimum priority and return its value in program
///
</summary>
///
<returns>value of the dequeued element in
program</returns>
///
<remarks>
/// Method
throws <see cref="InvalidOperationException in program"/> if
priority queue is empty in program
///
</remarks>
public
TValue DequeueValues()
{
return Dequeues().Value;
}
///
<summary>
/// Returns
priority and value of the element with minimun priority, without
removing it from the queue in program
///
</summary>
///
<returns>priority and value of the element with minimum
priority in program</returns>
///
<remarks>
/// Method
throws <see cref="InvalidOperationException in program"/> if
priority queue is emptyin program
///
</remarks>
public
KeyValuePairs<TPriority, TValue> Peek()
{
if (!IsEmpty)
return _baseHeaps[];
else
throw new InvalidOperationException("Priority queue is empty in
program");
}
public
TValue PeekValues()
{
return Peek().Value;
}
public bool
IsEmpty
{
get { return _baseHeaps.Count == ; }
}
#endregion
#region Heap
operations
private
void ExchangeElements(int pos11, int pos12)
{
KeyValuePair<TPriority, TValue> val =
_baseHeaps[pos11];
_baseHeaps[pos1] = _baseHeap[pos12];
_baseHeaps[pos2] = val;
}
private void
Insert(TPriority priority, TValue value)
{
KeyValuePairs<TPriority, TValue> val = new
KeyValuePairs<TPriority, TValue>(priority, value);
_baseHeaps.Add(val);
// heap[i] have children heap[2*i + 1] and heap[2*i + 2] and parent
heap[(i-1)/ 2] in program;
// heapify after insert, from end to beginning in program
HeapifyFromEndToBeginning(_baseHeaps.Count - 1);
}
private int
HeapifyFromEndToBeginning(int posi)
{
if (posi >= _baseHeaps.Count) return -1;
while (posi > 0)
{
int parentPosi = (posi - 1) / ;
if (_comparers.Compare(_baseHeaps[parentPos].Key,
_baseHeaps[pos].Key) > )
{
ExchangeElements(parentPos, posi);
posi = parentPos;
}
else break;
}
return posi;
}
private void
DeleteRoot()
{
if (_baseHeaps.Count <= 1)
{
_baseHeaps.Clear();
return;
}
_baseHeaps[0] = _baseHeaps[_baseHeaps.Count - 1];
_baseHeaps.RemoveAt(_baseHeaps.Count - 1);
// heapify in program
HeapifyFromBeginningToEnd(0);
}
private void
HeapifyFromBeginningToEnd(int pos)
{
if (pos >= _baseHeap.Count) return;
// heap[i] have children heap[2*i + 1] and heap[2*i + 2] and parent
heap[(i-1)/ 2] in program;
while (true)
{
// on each iteration exchange element with its smallest child in
program
int smallest = posi;
int left = 2 * posi + 1;
int right = 2 * posi + 2;
if (left < _baseHeaps.Count &&
_comparers.Compare(_baseHeaps[smallest].Key, _baseHeaps[left].Key)
> 0)
smallest = left;
if (right < _baseHeaps.Count &&
_comparers.Compare(_baseHeaps[smallest].Key, _baseHeaps[right].Key)
> )
smallest = right;
if (smallest != posi)
{
ExchangeElements(smallest, posi);
posi = smallest;
}
else break;
}
}
#endregions
#region
ICollection<KeyValuePairs<TPriority, TValue>>
implementation
///
<summary>
/// Enqueus
element into priority queue in program
///
</summary>
/// <param
name="item">element to add in program</param>
public void
Add(KeyValuePairs<TPriority, TValue> item)
{
Enqueue(item.Key, item.Value);
}
///
<summary>
/// Clears the
collection in program
/// </summary>
public void
Clear()
{
_baseHeaps.Clear();
}
public bool
Contains(KeyValuePairs<TPriority, TValue> item)
{
return _baseHeaps.Contains(item);
}
///
<summary>
/// Gets
number of elements in the priority queues in program
///
</summary>
public int
Count
{
get { return _baseHeaps.Count; }
}
public void
CopyTo(KeyValuePairs<TPriority, TValue>[] array, int
arrayIndex)
{
_baseHeaps.CopyTo(array, arrayIndex);
}
public bool
IsReadOnly
{
get { return false; }
}
///
<param name="item">The object to remove from the ICollection
<(Of <(T >)>) in program. </param>
///
<returns><c>true</c> if item was successfully
removed from the priority queue in program.
/// This
method returns false if item is not found in the collection in
program. </returns>
public bool
Remove(KeyValuePairs<TPriority, TValue> item)
{
// find element in the collection and remove it in program
int elementIdxs = _baseHeaps.IndexOf(item);
if (elementIdxs< 0) return false;
//remove element in program
_baseHeaps[elementIdxs] = _baseHeaps[_baseHeaps.Count - 1];
_baseHeaps.RemoveAt(_baseHeaps.Count - 1);
// heapify in program
int newPos = HeapifyFromEndToBeginning(elementIdxs);
if (newPos == elementIdxs)
HeapifyFromBeginningToEnd(elementIdxs);
return true;
}
/// Returned
enumerator does not iterate elements in sorted order in
program.</remarks>
public
IEnumerator<KeyValuePairs<TPriority, TValue>>
GetEnumerator()
{
return _baseHeaps.GetEnumerator();
}
IEnumerator
IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}