用python构建FIFO数据结构

用python构建FIFO数据结构,python,data-structures,Python,Data Structures,我只使用必要的方法创建了FIFO数据结构。使用.pop()方法时遇到问题 它正在成功地从队列中删除值,但未返回正确的值 class Node: def __init__(self, item): self.item = item self.next = None class Queue(Node): def __init__(self): self.first = None self.size = 0

我只使用必要的方法创建了FIFO数据结构。使用
.pop()
方法时遇到问题

它正在成功地从队列中删除值,但未返回正确的值

class Node:

    def __init__(self, item):
        self.item = item
        self.next = None


class Queue(Node):

    def __init__(self):
        self.first = None
        self.size = 0

    def append(self, item):
        if self.first == None:
            node = Node(item)
            self.first = node
        else:
            self.next = Node(item)

        self.size+=1

    def pop(self):
        if self.is_empty():
            raise Exception('Empty queue')

        item = self.first.item
        if self.next != None:
            self.first = self.next
        self.size-=1
        return item

    def is_empty(self):
        return self.size == 0
输入和输出:

>>> a = Queue()
>>> a.append(1)
>>> a.append(2)
>>> a.append(3)
>>> a.append(4)
>>> a.pop()
1
>>> a.pop()
4
>>> a.pop()
4
>>> a.pop()
4
>>> a.pop()
Traceback (most recent call last):
  File "<pyshell#81>", line 1, in <module>
    a.pop()
  File "D:/PERSONAL DATA/python/Online Compitions/Hackerrank/morgan_and_string.py", line 28, in pop
    raise Exception('Empty queue')
Exception: Empty queue
>a=Queue()
>>>a.1(1)
>>>a.2(2)
>>>a.3(3)
>>>a.3(4)
>>>a.流行音乐()
1.
>>>a.流行音乐()
4.
>>>a.流行音乐()
4.
>>>a.流行音乐()
4.
>>>a.流行音乐()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
a、 流行音乐()
文件“D:/PERSONAL DATA/python/Online comptions/Hackerrank/morgan_and_string.py”,第28行,pop格式
引发异常('空队列')
例外:空队列

是否有人可以帮助查找问题所在?

追加时,应该设置最后一个节点的
下一个
元素,而不是第一个节点。通过在类中同时具有
first
last
属性,可以更容易地实现这一点(否则,您需要一个循环来查找最后一个节点)

pop()
应始终将
self.first
设置为下一个节点,即使它是
None

class Queue():

    def __init__(self):
        self.first = None
        self.size = 0
        self.last = None

    def append(self, item):
        node = Node(item)
        if self.first is None:
            self.first = node
            self.last = node
        else:
            self.last.next = node
            self.last = self.last.next

        self.size+=1

    def pop(self):
        if self.is_empty():
            raise Exception('Empty queue')

        item = self.first.item
        self.first = self.first.next
        if self.first is None:
            self.last = None
        self.size-=1
        return item

    def is_empty(self):
        return self.size == 0

队列
也不需要成为
节点
的子类,它从不使用它继承的任何东西。

以下是对原始代码进行最小更改的更正代码

class Node:

    def __init__(self, item):
        self.item = item
        self.next = None


class Queue(Node):

    def __init__(self):
        self.first = None
        self.size = 0

    def append(self, item):
        if self.first == None:
            node = Node(item)
            self.first = node
        else:
            start = self.first
            while(start.next):
                start = start.next
            start.next = Node(item)

        self.size+=1

    def pop(self):
        if self.is_empty():
            raise Exception('Empty queue')

        item = self.first.item
        if self.first.next != None:
            self.first = self.first.next
        self.size-=1
        return item

    def is_empty(self):
        return self.size == 0

需要注意的是,item和next是Node类的属性,first和size是Queue类的属性。

在您的示例中,您将
队列
节点
继承,但似乎“节点”实际上是队列中的元素,而队列则管理整个事情。此外,您还将方法命名为“pop”和“push”,但对于队列,您通常谈论读写,因为对堆栈执行的是“pop”和“push”

考虑到这一点,下面的代码对您的代码进行了各种修复,但总体结构相同,我认为它可以按照您的预期工作:

class Node:
    def __init__(self, item):
        self.item = item
        self.next = None


class Queue:
    def __init__(self):
        self.first = None
        self.last = None
        self.size = 0

    def write(self, item):
        node = Node(item)

        if self.first is None:
            self.first = node

        if self.last is None:
            self.last = node
        else:
            self.last.next = node
            self.last = node

        self.size += 1

    def read(self):
        if self.is_empty():
            raise Exception('Empty queue')

        item = self.first.item

        self.first = self.first.next
        if self.first is None:
            self.last = None

        self.size -= 1
        return item

    def is_empty(self):
        return self.size == 0
关于主要差异的几点意见:

  • 队列不再从节点继承
  • .next
    用于节点实例,例如
    self.first.next
  • 我添加了一个
    .last
    ,因为您希望同时访问队列的开始和结束
下面是一些测试代码:

q = Queue()
q.write('a')
q.write('b')
print(q.read())
q.write('c')
print(q.read())
print(q.read())

# read from empty queue
print(q.read())
它适用于上面的问题,但对其他一些答案不起作用,但也许我不知道他们希望如何使用代码

输出:

a
b
c
Traceback (most recent call last):
  File "C:/dev/project/python/sandbox/q.py", line 53, in <module>
    print(q.read())
  File "C:/dev/project/python/sandbox/q.py", line 29, in read
    raise Exception('Empty queue')
Exception: Empty queue
a
B
C
回溯(最近一次呼叫最后一次):
文件“C:/dev/project/python/sandbox/q.py”,第53行,在
打印(q.read())
文件“C:/dev/project/python/sandbox/q.py”,第29行,已读
引发异常('空队列')
例外:空队列

你能分享你收到的输出吗?你把
队列
节点
混在一起了-例如,你在
append()
pop()
中设置了
self.next
,但是
节点
下一个
队列
没有。另外,对队列使用
pop
非常令人困惑,这是一个通常应用于堆栈的动词。@Grismar
queue
Node
@Barmar的子类-啊,你说得对,这进一步混淆了问题,因为“队列”不是“节点”@Grismar抱歉,请更清楚地解释它。我不明白。我不想要队列中的最后一个元素。如果你按小时付钱给我,你能不用它就实施吗?当然!你可以做@vishakhall显示的,
while(start.next):start=start.next start.next=Node(item)
,这是用一些计算换取额外变量。哈哈,很好。我没有提到,因为您希望同时访问队列的开始和结束。感谢您在回答中提供的详细信息。我们是否可以在没有
的情况下实现此功能。上次
?我已将其修复
self.next
应该是
self.first.next
。如果你没有
。last
你必须循环,就像@vishakhall的答案一样。谢谢。这意味着不使用循环,如果我想追加,那么。最后一个必须是必需的?如果要追加到队列的末尾,必须以某种方式找到最后一个节点。