pythondata-structurespriority-queuecircular-queue

An efficient way to implement circular priority queue?


I have designed a circular priority queue. But it took me a while because it is so conditional and has a bit much of a time complexity.

I implemented it using a list. But I need a more efficient circular priority queue implementation.

I'll illustrate my queue structure, sometimes it would be helpful for someone who seeks for a code to understand circular priority queues.

class PriorityQueue:

    def __init__(self,n,key=None):
        if key is None:
            key=lambda x:x
        self.maxsize = n
        self.key=key
        self.arr = list(range(self.maxsize))
        self.rear = -1
        self.front = 0
        self.nelements=0

    def isPQueueful(self):
        return self.nelements==self.maxsize

    def isPQueueempty(self):
        return self.nelements==0

    def insert(self, item):

        if not self.isPQueueful():
            pos=self.rear+1
            scope = range(self.rear - self.maxsize, self.front - self.maxsize - 1, -1)
            if self.rear==0 and self.rear<self.front:
                scope=range(0,self.front-self.maxsize-1,-1)
            for i in scope:
                if self.key(item)>self.key(self.arr[i]):
                    self.arr[i+1]=self.arr[i]
                    pos=i
                else:
                    break
            self.rear+=1
            if self.rear==self.maxsize:
                self.rear=0
            if pos==self.maxsize:
                pos=0
            self.arr[pos]=item
            self.nelements+=1
        else:
            print("Priority Queue is full")

    def remove(self):

        revalue=None
        if not self.isPQueueempty():
            revalue=self.arr[self.front]
            self.front+=1
            if self.front==self.maxsize:
                self.front=0
            self.nelements-=1

        else:
            print("Priority Queue is empty")
        return revalue

I really appreciate if someone can say whether what I designed is suitable for used in a production code. I think mostly it is not an efficient one.

If so can you point out to me how to design a efficient circular priority queue?


Solution

  • So, think of the interface and implementation separately.

    The interface to a circular priority queue will make you think that the structure is a circular queue. It has a "highest" priority head and the next one is slightly lower, and then you get to the end, and the next one is the head again.

    The methods you write need to act that way.

    But the implementation doesn't actually need to be any kind of queue, list, array or linear structure.

    For the implementation, you are trying to maintain a set of nodes that are always sorted by priority. For that, it would be better to use some kind of balanced tree (for example a red-black tree).

    You hide that detail below your interface -- when you get to the end, you just reset yourself to the beginning -- your interfaces makes it look circular.