链接列表,删除尾部功能

时间:2018-02-20 19:40:00

标签: c function pointers memory-management linked-list

我正在尝试为链接列表构建头部删除和尾部删除功能。

我已成功删除头部,但我的尾部删除功能实际上并没有删除尾部。

首先,如何创建链接列表:

typedef struct node
{
    int data;
    struct node *next;

} node;

typedef struct LinkedList
{
    node *head;
    node *tail;

} LinkedList;

node *createNode(int data)
{
    node *new_node;

    if ((new_node = malloc(sizeof(node))) == NULL)
        return NULL;

    new_node->data = data;
    new_node->next = NULL;

    return new_node;
}

LinkedList *createLinkedList(void)
{
    LinkedList *LL;

    if ((LL = calloc(1, sizeof(LinkedList))) == NULL)
        return NULL;

    return LL;
}

void tailInsert(LinkedList *LL, int data)
{

    if (LL == NULL)
        return;

    if (LL->tail == NULL)
    {
        LL->head = LL->tail = createNode(data);
        return;
    }

    LL->tail->next = createNode(data);
    LL->tail = LL->tail->next;

}

这是两个功能:

这个不起作用:

int tail_Delete(LinkedList *list)
{
    int retval;
    node *temp;

    if (list == NULL || list->head == NULL)
        return EMPTY_LIST_ERR;

    // if only one node
    if (list->head->next == NULL)
    {
        retval = list->head->data;
        free(list->head);
        list->head = NULL;
        list->tail = NULL;
        return retval;
    }

    // make temp the node before the tail
    for (temp = list->head; temp->next != list->tail; temp = temp->next)
        ;

    retval = list->tail->data;

    free(list->tail);

    list->tail = temp;

    return retval;
}

这个确实有效:

int head_delete(LinkedList *list)
{
    int retval;
    node *temp;

    if (list == NULL || list->head == NULL)
        return EMPTY_LIST_ERR;

    retval = list->head->data;

    temp = list->head->next;

    free (list->head);

    list->head = temp;

    if (list->head == NULL)
        list->tail = NULL;

    return retval;
}

打印功能和主要:

void print_Linked_list(LinkedList *LL)
{
    node *temp;

    if (LL == NULL || LL->head == NULL)
        return;

    for (temp = LL->head; temp != NULL; temp = temp->next)
        printf("%d%c", temp->data, (temp->next == NULL) ? '\n' : ' ');

}

int main(void)
{
    LinkedList *LL;
    int val;

    LL = createLinkedList();

    tailInsert(LL, 1);
    tailInsert(LL, 2);
    tailInsert(LL, 3);

    print_Linked_list(LL);

    val = tail_Delete(LL);
    //val = head_delete(LL);

    printf("%d\n", val);

    print_Linked_list(LL);

    return 0;
}

head_delete的输出:

1 2 3
Deleted node: 1
2 3

tail_delete的输出:

1 2 3
Deleted node: 3
1 2 3

这可能是一个简单的错误,但它们似乎实际上是等效的功能。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

执行temp->next循环时,应该为for指针赋值0。通过这个你指出这个元素是最后一个。

for (temp = list->head; temp->next != list->tail; temp = temp->next)
    ;

temp->next = 0; // <---

retval = list->tail->data;

答案 1 :(得分:1)

需要在尾部之前从节点管理尾部删除。如果你没有在列表中有一个后退指针(双重链接),那么你需要向前走到尾部。

未经测试,尾部删除(没有后退指针)应如下所示。

LinkedList *node = list->head;
LinkedList *next = node->next;

while(next != list->tail) {  // walk to the end
    node = next;
    next = node->next;
}
// now node is the node before the tail and next is the tail
int retval = next->data;
free(next);
// this is why we needed to walk here
node->next = NULL;