我试图建立一个头部删除和尾部删除功能的链接列表。
我已经成功删除了头部,但我的尾部删除功能实际上并没有删除尾部。
首先,如何创建链接列表:

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

尾部删除的输出:
1 2 3
Deleted node: 3
1 2 3

这可能是一个简单的错误,但它们似乎实际上是等价的函数。
谢谢你的帮助。

最佳答案

尾部删除需要从尾部之前的节点进行管理。如果列表中没有后退指针(双链接),则需要向前走到尾部。
未经测试的tail delete(没有back指针)应该是这样的。

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;

关于c - 链表,删除尾部功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48892992/

10-11 18:45