C语言 删除链表中具有一定值的所有节点



标题不言自明。下面是我为此目的编写的函数:

void wipeLoneCells()
{
    cell *tmp;
    tail = head;
    while (1)
    {
        if (head == tail && !tail->flag)
        {
            head = head->next;
            free(tail);
            tail = head;
            continue;
        }
        tmp = tail->next;
/***/   if (tmp->next == NULL && !tmp->flag)
        {
            tail->next = NULL;
            free(tmp);
            break;
        }
        else if (!tmp->flag)
        {
            tail->next = tmp->next;
            free(tmp);
            continue;
        }
        tail = tail->next;      
    }
}

列表的头和尾是全局的,并且在调用此函数时构建列表,其中头指向第一个节点,尾指向最后一个节点(其下一个节点为NULL)。我几乎可以肯定我的链表是正确构建的,因为我可以打印它们而没有错误。有时这个函数可以完美地工作,有时它会在标有星号的行处导致访问冲突。我知道这不是完全错误的,因为当我得到我想要的结果时,它不会产生错误,尽管我经常得到错误,所以一定有什么我忽略了。提前感谢您的帮助。

编辑:这是固定代码:

void wipeLoneCells()
{
    cell *tmp;
    tail = head;
    while (1)
    {
        if (head == tail && !tail->flag)
        {
            head = head->next;
            free(tail);
            tail = head;
            continue;
        }
        tmp = tail->next;
        if (tmp->next == NULL && !tmp->flag)
        {
            tail->next = NULL;
            free(tmp);
            break;
        }
        else if (tmp->next == NULL)
        {
            tail = tmp;
            break;
        }
        else if (!tmp->flag)
        {
            tail->next = tmp->next;
            free(tmp);
            continue;
        }
        tail = tail->next;      
    }
}

如果

tmp = tail->next; 

NULL ?下一行试图解引用NULL指针,这会导致未定义的行为—可能导致崩溃。

您应该检查这种情况并采取适当的措施。

单链表中正确的deleteitem()如下:

您可以避免递归并提出迭代版本(尝试一下,但如果需要帮助请告诉我)。我不会在这种情况下使用while(1) !

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

/*
(1) deleting head 
    delete element and adjust head pointer
(2) deleting tail
    delete element and adjust tail pointer
(3) one element list
    if data is the data for the only element
    then delete the list and set head and tail
    pointers to NULL
(4) all the other cases
    traverse through the list and hold the
    previous pointer. delete element and adjust
    the next pointers. 
(5) if not the above cases, then element not
    present.. do nothing..
*/
void deleteitem(int data)
{
    printf("%s: %d - ", __FUNCTION__, data);
    NODE *cur = head;
    NODE *prev = cur;
    NODE *temp = NULL;
    if (head == NULL) {
        assert (tail == NULL);
        printf("Empty list n");
        return;
    }
    if (head->data == data) {
        temp = head;
        // one element list
        if (head == tail)
            head = tail = NULL;
        else
            // list has more than one element
            head = head->next;
        printf("%d n", temp->data);
        free(temp);
        deleteitem(data);
        return;
    }
    while (cur != NULL) {
        if (cur->data == data) {
            if (cur == tail) {
                tail = prev;
            }
            prev->next = cur->next;
            printf(" %d deletedn", cur->data);
            free(cur);
            assert(tail->next == NULL);
            deleteitem(data);
            return;
        }
        prev =cur;
        cur = cur->next;
    }
    printf(" %d not foundn", data);
    return;
}

相关内容

  • 没有找到相关文章

最新更新