链接列表中的头节点是否有任何信息,或者它是否仅指向链接列表的第一个节点?
我们可以将头节点定义为链接列表的起始节点吗?
头节点是否仅指向第一个节点?
链表由节点组成,每个节点包含一些数据和指向列表中另一个节点的链接。但是第一个节点是包含数据的节点还是到第二个节点的链接?或者它只包含一个节点的链接(没有数据)?我认为链表中的第一个节点既有数据又有到另一个节点的链接,但在一本介绍性书中,解释说head是一个节点,但是一个链接可以将你带到第一个节点。同时head是节点类型的变量。为什么会这样?
答案 0 :(得分:3)
这取决于实施。 head
变量通常是节点指针,它指向列表中的第一个节点,例如在这个单节点列表中:
+--------+
head -> | node 1 | -> NULL
+--------+
但是,我已经看到了“空”(双链接)列表由两个节点组成的实现,因此插入和删除代码不必担心尝试在头部之前或之后插入的边缘情况尾部,或头部/尾部的删除。
由于您要插入的每个位置(以及您允许删除的每个节点)都有prev
和next
节点,因此代码已简化。
+-------+ +------+ +-------+
head -> | dummy | -> | node | -> | dummy | -> NULL
NULL <- | node | <- | 1 | <- | node | <- tail
+-------+ +------+ +-------+
不是大量检查头部或尾部,而是插入和删除:
def insertBefore (node, newnode):
newnode.next = node
newnode.prev = node.prev
node.prev.next = newnode
node.prev = newnode
def deleteNode (node):
node.prev.next = node.next
node.next.prev = node.prev
free node
稍微复杂的列表遍历,因为您必须从curr = head.next
而不是curr = head
开始,并在curr == last
而不是curr == NULL
时完成,但是一些人认为这是一个有效的权衡,代价是两个未使用的节点。
答案 1 :(得分:1)
你可以至少以三种不同的方式做到这一点
每个都需要权衡某些操作,或优化使用的空间。
具有与其他节点相同类型的头对象简化了一些链接操作。拥有没有数据有效负载的头节点可以节省内存。将指针存储在列表对象中可能会为空列表保存动态分配,但会使swap
更难实现。
没有一个绝对是最适合所有用途的。
答案 2 :(得分:0)
传统上,头节点是链表的第一个节点,但从“类型”的观点来看,它与任何其他节点没有区别。它确实包含数据以及指向下一个节点的指针(链表的第二个节点,如果存在)。