1
\$\begingroup\$

I'm working on a custom implementation of A-Star and so I had to also create a Priority Queue and so I had to create a Heap. I'm quite happy with my Heap but I'm a bit worried about my Priority Queue: it is done and it works, but I am still wondering if the way I have done it will come back and bite me in the ass later.

Here is the code for my abstract PriorityQueue class:

    public abstract class PriorityQueueAbstract<T, TPriority>
    {
        HeapAbstract<Tuple<T, TPriority>> heap;
        protected PriorityQueueAbstract(HeapAbstract<Tuple<T, TPriority>> heapImplementation) => heap = heapImplementation;
        public void Enqueue(T item, TPriority priority) => heap.Insert(new Tuple<T, TPriority>(item, priority));
        public T Dequeue() => heap.Extract().Item1;
    }

And here is how I make a concrete class out of it:

    public class MinPriorityQueue<T, TPriority> : PriorityQueueAbstract<T, TPriority> where TPriority : IComparable
    {
        public MinPriorityQueue() : base(new Heap<Tuple<T, TPriority>>(new T2Comparer<T, TPriority>())) { }
    }

I have a version of Heap that works using a Comparer implementation as a parameter, which is why I'm instantiating a Tuple comparer and why TPriority needs to be an IComparable("T2Comparer", maybe I should give it a better name, I take suggestions).

But I could also setup my Priority Queue this way:

    public abstract class PriorityQueueAbstract<T, TPriority> : HeapAbstract<Tuple<T, TPriority>>
    {
        public void Enqueue(T item, TPriority priority) => Insert(new Tuple<T, TPriority>(item, priority));
        public T Dequeue() => Extract().Item1;
    }

And have the concrete class be:

    public class MinPriorityQueue<T, TPriority> : PriorityQueueAbstract<T, TPriority> where TPriority : IComparable
    {
        protected override int Compare(Tuple<T, TPriority> firstItem, Tuple<T, TPriority> secondItem)
        {
            return firstItem.Item2.CompareTo(secondItem.Item2);
        }
    }

The second option implements a Compare method because that's how my Heap is implemented.

I feel like the second option is more clear and easy to understand, extend etc. But my issue is that since it directly implements a Heap, you have access to its Insert and Extract methods on top of the Queue and Dequeue. I could hide them but I feel like that would be an ugly way to solve this.

I should also explain that I don't have access to the latest versions of NET if it wasn't clear.

What should I do in this case? What are the best practices? Is there a better way to do this?

\$\endgroup\$
3
  • \$\begingroup\$ Rather than reinventing the wheel have you looked around on nuget.org? For example \$\endgroup\$ Commented Nov 14, 2022 at 19:00
  • \$\begingroup\$ @Peter Csala Yes I did, but I wanted to implement it myself for learning purposes, which is why I'm asking about possible improvements. \$\endgroup\$
    – Caïn
    Commented Nov 14, 2022 at 19:32
  • 2
    \$\begingroup\$ Could you please share with the HeapAbstract as well? \$\endgroup\$ Commented Nov 15, 2022 at 10:49

0