Python使用优先级插入

时间:2013-11-02 21:05:22

标签: python insert

from myNode import *
from tasks import *

class PriorityQueue():
    __slots__ = ( 'front', 'back', 'size' )

def mkPriorityQueue():
    queue = PriorityQueue()
    queue.front = NONE_NODE
    queue.back = NONE_NODE
    queue.size = 0
    return queue

def insert(queue, element):
    newnode = mkNode(element, NONE_NODE)
    if emptyQueue(queue):
        #if the queue was empty, the new node is now both the first and last one
        queue.front = newnode
        queue.back = newnode
    elif frontMax(queue).priority > newnode.data.priority:
        #if the new node has a higher priority than the first, insert at front
        newnode.next = queue.front #old first is now second node
        queue.front = newnode
    else:
        #the node has a lower priority than the first
        #find the next node with a lower priority, insert newnode before that
        currentnode = queue.front
        while not currentnode.next == NONE_NODE:
            #traverse nodes until we find a lower priority or until the end
            if currentnode.next.data.priority < newnode.data.priority:
                break
            currentnode = currentnode.next
        #insert newnode between currentnode and currentnode.next
        newnode.next = currentnode.next
        currentnode.next = newnode
        #if newnode.next is now NODE_NONE, we're at the end so change backMin
        if newnode.next == NONE_NODE:
            queue.back = newnode

    queue.size += 1

def removeMax(queue):
    """Remove the front element from the queue (returns None)"""
    if emptyQueue(queue):
        raise IndexError("Cannot dequeue an empty queue")
    queue.front = queue.front.next
    if emptyQueue(queue):
        queue.back = NONE_NODE
    queue.size -= 1

def frontMax(queue):
    """Access and return the first element in the queue without removing it"""
    if emptyQueue(queue):
        raise IndexError("front on empty queue")
    return queue.front.data

def backMin(queue):
    """Access and return the last element in the queue without removing it"""
    if emptyQueue(queue):
        raise IndexError("back on empty queue")
    return queue.back.data

def emptyQueue(queue):
    """Is the queue empty?"""
return queue.front == NONE_NODE

我这样做了吗?以下是我想解决的问题。我添加了我所做的所有功能。

使用优先级规则插入(在插入函数下)(每个任务的整数优先级为10     (最高优先级)为1(最低优先级)。如果两个任务具有相同的优先级,则顺序应基于     命令将它们插入优先级队列(先前更早)。

1 个答案:

答案 0 :(得分:0)

首先,你的else语句中有一个语法错误,它没有采用测试表达式。除此之外,你的逻辑是关闭的,因为它不会在insert中保持正确的节点结构 - 当你执行queue.firstMax = newnode时,你基本上删除当前的firstMax元素,因为你不再有参考它;在这种情况下,您需要将旧的第一个元素分配给newnode.next。此外,如果新任务的优先级是<=当前的第一个,您将需要遍历队列以找到新节点维护顺序的正确位置 - 它应该在第一个元素之前优先级较低。 (在优化的实现中,您将存储按优先级分隔的节点,或者至少保留对每个优先级的最后节点的引用,以加快此插入,但我想这不在本练习的范围内。)

这是insert的一个应该正确执行的实现:

def insert(queue, element):
    newnode = mkNode(element, NONE_NODE)
    if emptyQueue(queue):
        #if the queue was empty, the new node is now both the first and last one
        queue.frontMax = newnode
        queue.backMin = newnode
    elif frontMax(queue).priority > newnode.data.priority:
        #if the new node has a higher priority than the first, insert at front
        newnode.next = queue.frontMax #old first is now second node
        queue.frontMax = newnode
    else:
        #the node has a lower priority than the first
        #find the next node with a lower priority, insert newnode before that
        currentnode = queue.frontMax
        while not currentnode.next == NODE_NONE:
            #traverse nodes until we find a lower priority or until the end
            if currentnode.next.data.priority < newnode.data.priority:
                break
            currentnode = currentnode.next
        #insert newnode between currentnode and currentnode.next
        newnode.next = currentnodenode.next
        currentnode.next = newnode
        #if newnode.next is now NODE_NONE, we're at the end so change backMin
        if newnode.next == NODE_NONE:
            queue.backMin = newnode

    queue.size += 1