【问题标题】:Am implementing a queue in python, What is making the dequeue part not to work?我在 python 中实现一个队列,是什么使出队部分不起作用?
【发布时间】:2016-10-31 15:52:33
【问题描述】:

AM 在 python 中实现一个队列。我已经完成的代码如下,但我无法弄清楚如何删除队列中的最后一项。我的实现显然是正确的。我在代码中遗漏了什么

class Queue:

    class node:
        def __init__(self):
            self.data = None
            self.next = None

    def __init__(self):
        self.cur_node = None
        self.head = None
    def isEmpty(self):
        return self.head==None

    def push(self,data):
        new_node = self.node()
        if self.head == None:
            new_node.data=data
            new_node.next=None
            self.head = new_node
            self.cur_node = None

        else:
            new_node.data = data
            node=self.head
            self.cur_node=node
            new_node.next=self.cur_node
            self.head=new_node
        #set it to head and change current head to next



    def list_print(self):
        node = self.head
        while node:
            print (node.data)
            node = node.next

    def dequeue(self): # A Queue IMPLEMENTS ITS STRUCTURE AS FIFO ( First IN First OUT)
        if self.head == None:
            raise Exception("Queue is empty")            
        else:# Remove the  last item which entered first
            node=self.head
            prevnode=node
            nodetodel=node
            while node:
                if node.next==None:
                    nodetodel=node
                    print(node.data)
                    node=node.next
                else:
                    #print(node.data)
                    node=node.next
                    prevnode=node

            self.cur_node=prevnode
            self.cur_node.next=None
            print(node.data)
            del(node)
lyst = ["Bill", "David", "Susan", "Jane", "Kent", "Brad"]
n=Queue()
for name in lyst:
    n.push(name)
n.dequeue()
#n.list_print()
print("Done")

【问题讨论】:

  • 您遇到的具体问题是什么?
  • 出队未按预期工作。程序在此时停止,最后一条语句`print("Done")没有输出,说明删除有问题

标签: python linked-list queue


【解决方案1】:

在我看来,您好像已经反向实现了您的 Queuehead 不应该跟踪Queue 中最旧的值吗?然后要出列,您只需执行self.head = self.head.next 之类的操作。这是一个快速实现

class Queue:

    class EmptyQueue(Exception):
        def __str__(self):
            return "Queue is empty, cannot dequeue."    
    class node:
        def __init__(self, data, next):
            self.data = data
            self.next = next

    def __init__(self, seq=None): 
        self.head = None #Oldest item in queue
        self.tail = None #Youngest item in queue
        if seq:
            for item in seq:
                self.enqueue(item)

    def enqueue(self, item):
        new_node = Queue.node(item, None)
        if not self.tail: #queue empty
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node

    def dequeue(self):
        if self.head:
            data = self.head.data
            self.head = self.head.next
            return data
        else:
            raise Queue.EmptyQueue

    def list_print(self):
        curr = self.head
        while curr:
            print(curr.data)
            curr = curr.next

【讨论】:

  • 这个有错误~File "C:\Users\Issaco\Documents\EC Chapter 03\jn.py", line 43, in <module> n.enqueue(name) File " ----\jn.py", line 18, in enqueue new_node = node(item, None) NameError: name 'node' is not defined
  • @BroNick 您可以将两个类定义移出Queue 或将它们称为Queue.node(...)
【解决方案2】:

我在代码中遗漏了什么

没有使用nodetodel

        #print(node.data)
        node=node.next
        prevnode=node

您应该在更改节点之前设置 prevnode,而不是之后。

    self.cur_node=prevnode
    self.cur_node.next=None

cur_node 作为成员变量是没用的,你不要在任何情况下使用它,局部变量会很容易地完成这项工作并且你已经有一个(prevnode)

    print(node.data)
    del(node)

在执行这两行时,您已经拥有 node==None ,这是程序崩溃的原因。可能你想使用 nodetodel intead。

附:我只是指出您在代码中遗漏的内容 - 正如您所要求的那样。我希望它会有所帮助,即使我个人相信在修复并确保它可以以某种方式工作后,您会考虑@PatrickHaugh 的答案并从头开始。

队列的实现效率很低,因为它必须遍历链表的每个元素。头/尾保持优化的关键是避免需要遍历整个列表来执行push/pop。

【讨论】:

    【解决方案3】:

    dequeue 中的 if node.next==None 部分在 print 语句的上下文中是错误的。我认为以下更正确(我也简化了):

    def dequeue(self): # A Queue IMPLEMENTS ITS STRUCTURE AS FIFO ( First IN First OUT)
        if self.head == None:
            raise Exception("Queue is empty")            
        else:# Remove the  last item which entered first
            node=self.head
            prev = None
            while node:
                if node.next:
                    prev = node = node.next
                else:
                    self.cur_node = prev
                    if prev:
                        prev.next = None
                    return node.data
    

    但在实际使用中你可能只使用内置列表(可以用作队列)或 queue.queue,后者是并发安全的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 2014-04-21
      • 2015-07-06
      • 1970-01-01
      • 2015-08-10
      相关资源
      最近更新 更多