我正在学习节点和链接队列(这些与链表几乎相同吗?)而且我还没有完全理解节点是什么。它是一个节点,是列表中引用下一个元素的元素吗?我正在从这个网站上学习 http://openbookproject.net/thinkcs/python/english3e/queues.html并使用此代码:
class Queue:
def __init__(self):
self.length = 0
self.head = None
def is_empty(self):
return self.length == 0
def insert(self, cargo):
node = Node(cargo)
if self.head is None:
# If list is empty the new node goes first
self.head = node
else:
# Find the last node in the list
last = self.head
while last.next:
last = last.next
# Append the new node
last.next = node
self.length += 1
def remove(self):
cargo = self.head.cargo
self.head = self.head.next
self.length -= 1
return cargo
我真的需要了解node
和cargo
是什么,提前谢谢
答案 0 :(得分:2)
将链接列表可视化为"框和指针"图。
粘在一起的盒子对是你的程序调用节点的东西。这两个框表示节点的两个部分。一个盒子(指向)"货物"另一个持有" next"。一个节点有两个部分,一个"货物"和"下一个"。
" next"节点的成员要么指向另一个节点,要么指向任何节点(" NIL"在上图中)。 "货物",好吧,是货物。
在上面的列表中,包含42个货物的节点是列表的头部。你的队列只需要抓住头部。使用" next"队列中的节点成员可以" walk"获取每个元素的列表。
我假设某处有一个Node类定义如下:
class Node:
def __init__(self, cargo):
self.cargo = cargo
self.next = None
要了解队列的工作原理,请在图片中构建队列。
首次创建队列对象时,队列头指针指向“无”以表示空队列。
q = Queue()
要将第一项添加到队列,请插入42
q.insert(42)
insert函数创建一个包含42的节点,并将该节点插入到head位置,因为还没有其他节点。它还将长度从1增加到0.
要将第二项添加到队列,请插入69。
q.insert(69)
insert函数创建一个包含69的节点。然后它" walk"链接列表,直到它到达下一个成员中没有None的节点。然后它将该节点的下一个成员更改为指向新节点。插入也会增加队列长度。
要添加613,它会重复用于添加69的过程。链接列表会更长,但过程是相同的。
q.insert(613)
此时,表示队列的链表是图片中显示的列表。
从队列中检索第一项:
x = q.remove()
删除功能查看头节点的货物。它包含42.存储该值以在队列进行簿记后返回。需要从队列的前面删除包含42的节点,并且下一个节点需要移动到头部。要执行此操作,remove函数将从当前头节点获取下一个节点,并将其粘贴到队列头部位置。旧的头节点现在是一个孤儿,没有人指向它,所以垃圾收集器将确保它被清理。新链接列表是图像中的最后两个节点。然后货物返回给调用者并存储在x。
从队列中检索下一个项目:
y = q.remove()
重复相同的过程,除了头节点的货物是69,下一个节点是货物是613的节点。在此函数之后,调用y包含69并且队列中的链表仅包含包含613的节点
附录:走一个链表:
Node.insert()中的while循环" walk"链表。在这个功能"最后"是变量的坏名称。它应该只是节点,因为在while循环期间,它指向链接列表中的每个节点,用于while循环的一次迭代。 (Node.next应该是Node.tail,但那是另一个时间的参数。)
在循环开始之前,变量last被分配了头节点。 last = self.head。 (在大多数情况下,头节点不是最后一个节点,因此是坏变量名称)while循环条件" last.next"检查当前在变量中的节点(大部分时间不是最后一个节点)是否实际上最后一个节点。实际的最后一个节点在其最后一个成员中将为None,而作为Boolean的None为false。如果一个节点在其最后一个成员中没有None,则它的最后一个成员指向下一个节点。所以到了步骤"到链接列表中的下一个节点,while循环的主体最后分配给当前最后一个节点中的节点。
扩展上面的示例:考虑插入613的步骤。在插入613之前,链表是两个节点。头节点(由队列对象的self.head指向)包含其中的42个货物成员,并包含其下一个成员中的第二个链接。第二个链接包含69个货物,其中包含下一个成员。第二个链接是列表的最后一个链接。
要遍历列表,接下来的变量将分配给其中包含42个货物的链接。 (此时变量last not 指向列表中的最后一个链接。)while循环条件查看变量last(第一个链接)中链接的下一个成员,以确定如果它包含无。它没有,所以while循环的主体执行。 while循环的主体将节点放在变量last(第一个节点的下一个成员)中包含的节点的最后一个成员中,并将该节点放在名为last的变量中。环的主体结束。此时,while循环评估循环条件。当前在变量last 中的节点实际上是最后一个节点(记住,我们正在追加包含613的节点,因此列表只有两个节点)所以last.next是None。 while循环终止,此时变量last实际上包含最后一个节点。
希望你可以看到这对于更长的列表是如何工作的,但是需要更多的词来描述。
总结一下,(相关队列,链接列表,头部,节点,货物和nexts):您的队列指向链接列表的头部,链接列表由包含货物和nexts的节点组成。队列在链接列表的末尾插入新项目,并从链接列表的头部删除项目。希望一切都有意义。
答案 1 :(得分:1)
“节点”是链接列表中的项目 - 它是链接的内容。 “头部”是衬里链中的第一个节点。 “cargo”是节点中包含的数据。 “队列”是一种列表形式,具有开始和结束,按顺序进行,先进先出(与堆栈相对,后进先出,或循环。
答案 2 :(得分:1)
在此特定示例中,node
包含树中其邻居(next
)的信息,以便它可以遍历列表。它还包含对cargo
的引用,它是存储在节点中的实际数据。
这里要理解的另一个重要变量是head
,它始终是树中的第一个(前)节点。由于这是一个队列(特别是FIFO队列),remove
(在其他实现中通常称为pop
)函数返回cargo
的{{1}}为以及将其从队列中删除并将队列的新head
设置为旧head
的{{1}}。