【问题标题】:Dummy nodes in Linked List implementation链表实现中的虚拟节点
【发布时间】:2019-08-28 05:59:28
【问题描述】:

我正在尝试实现单链表。

要求是: 1.按数据顺序插入 2. 从头部移除

在我的实现中是否需要一个虚拟节点? 虚拟节点也应该放在列表的开头还是列表的末尾?

我搜索了答案,发现虚拟节点在删除列表中的最后一个节点时很有帮助。但是,我无法理解如何。 谁能解释一下?

【问题讨论】:

  • 不,但可能想要。在哪里更有用,请考虑将其放在最后。那会有帮助吗?考虑它是在开始。那会有帮助吗?因为它简化了代码的几个部分,尤其是删除,尤其是在删除头节点时。在那里,我回答了你所有的问题。现在选择一个以获得更多详细信息。堆积问题会使您的帖子过于宽泛。
  • 请至少开始自己做点什么。从创建列表开始。然后拿出笔和纸,开始画几个盒子,盒子之间有棱线。然后开始考虑删除,这是最难的部分。

标签: c data-structures linked-list singly-linked-list


【解决方案1】:

链接列表如下所示:

struct list_node {
    struct list_node *next;
    void *data;
};

struct list_node *head;

C 中的链表中永远不需要虚拟节点。

虚拟节点用于允许“删除当前”操作在不提供指向指针的语言的单链表中实现。就是这样。

当你有一个指向节点的指针时,你可以通过移动下一个节点并释放下一个节点来删除该节点。虚拟节点确保始终有下一个节点来执行此操作。

但是,在 C 中,最好通过保持指向下一个节点的指针来为您服务。在迭代开始时,这是一个指向head 的指针;在开始之后,这是一个指针list_node::next,其中list_node 是先前查看的节点。

【讨论】:

  • 感谢您的回答,这很有帮助。所以如果我必须实现“删除当前”操作,我不能在没有虚拟节点的情况下做吗?如果假设要删除的节点是最后一个节点,我可以将它上面的下一个节点设置为 NULL 对吗?如果我遗漏了什么,请纠正我
  • @Shruthi:正确。我阐明了方法的精髓。
  • 现在我明白虚拟节点非常重要,以防我们不希望有指向指针实现的指针,这在我的情况下是正确的。我正在标记这个答案。谢谢!
【解决方案2】:

实现单链表不需要虚拟节点。它们被用作定义与列表元素结构不同的列表结构的替代方法。

根据您的要求,您应该定义一个列表结构,其中包含一个指向列表头部的指针和一个指向列表尾部的指针。这将使两个操作,在末尾插入和从头部移除都运行 n 个恒定时间。

当列表为空时,必须注意正确维护这些指针。

这是一个简单的例子:

struct list_elem_s {
    struct list_elem_s *next;
    int data;
    //... other payload fields
};

struct list_s {
    struct list_elem_s *head;
    struct list_elem_s *tail;
};

// initialize a list as empty
void list_initialize(struct list_s *list) {
    list->head = list->tail = NULL;
}

// free all elements from a list
void list_delete(struct list_s *list,
                 void (*free_node)(struct list_elem_s *node)) {
    struct list_elem_s *node;
    while ((node = list->head) != NULL) {
        list->head = node->next;
        node->next = NULL;
        if (free_node)
            free_node(node);
    }
    list->tail = NULL;
}

// add a node at the tail
void list_push(struct list_s *list, struct list_elem *node) {
    node->next = NULL;
    if (list->tail) {
        list->tail->next = node;
    } else {
        list->head = node;
    }
    list->tail = node;
}

// remove a node at the head
struct list_elem *list_pop_head(struct list_s *list) {
    struct list_elem_s *node;
    if ((node = list->head) != NULL) {
        if ((list->head = node->next) == NULL)
            list->tail = NULL;
    }
    return node;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多