使用尾指针删除单个链表的最后一个节点

时间:2017-08-05 17:13:48

标签: c pointers linked-list singly-linked-list

我在C中创建一个单链表,它有头尾指针,其中头指针指向SLL的起始节点,尾指针指向SLL的最后一个节点。我不想使用头指针遍历列表的末尾来删除节点。有没有办法让我可以使用尾指针删除SLL的最后一个元素?

以下是节点添加功能。头部和尾部被启动为NULL。

void add_node_last(Node** head, Node** tail, int data) {

    Node* new_node = (Node *) malloc(sizeof(Node));

    new_node -> data = data;
    new_node -> ptr  = NULL;

    if(*head == NULL && *tail == NULL) {
        *head = new_node;
        *tail = new_node;
        return;
    }

    (*tail) -> ptr = new_node;

    *tail = new_node;

}

要删除第一个节点,请使用以下函数:

void del_first(Node **head) {
    if(*head == NULL) {
        return;
    }
    *head = (*head) -> ptr;
    free(*head);
}

2 个答案:

答案 0 :(得分:2)

您可以释放节点的内存,但只能释放一次。第一次删除后,您的尾指针和倒数第二个节点的ptr将是无效指针。为了确保两个指针始终正确,您需要遍历整个列表或使其成为双向链表。

这说不了(感谢@stark)。

答案 1 :(得分:0)

为了使其在不使其成为双向链表的情况下工作,您可以让尾部的*下一个指针指向列表的头部,然后遍历它直到您到达尾部之前的节点。一旦你在那里你可以NULL其*下一个指针,这将基本上从列表中分离原始尾部。然后你将尾部设置为当前节点,然后最终释放原始尾部。

void del_last(Node **head, Node **tail) {
    struct node *new_head = *head;
    struct node *current = *tail;

    current->next = head;

    while(current-> != *tail)    //getting the node right before the original tail
    {
         current = current->next
    }

    current->next = NULL;   //detaches original tail form list

    free(**tail);   //gets rid of original tail
    **tail = current;   // sets current node to tail pointer
}