需要帮助理解节点和链表

时间:2014-01-16 01:13:04

标签: python linked-list

我正在学习节点和链接队列(这些与链表几乎相同吗?)而且我还没有完全理解节点是什么。它是一个节点,是列表中引用下一个元素的元素吗?我正在从这个网站上学习 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

我真的需要了解nodecargo是什么,提前谢谢

3 个答案:

答案 0 :(得分:2)

将链接列表可视化为"框和指针"图。

Box & pointer diagram of a linked list

粘在一起的盒子对是你的程序调用节点的东西。这两个框表示节点的两个部分。一个盒子(指向)"货物"另一个持有" 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}}。