【问题标题】:Can't delete a node using a condition in circular linked list in c无法使用c中循环链表中的条件删除节点
【发布时间】:2018-01-27 15:23:47
【问题描述】:

我有一个如下的循环链表,用于保存待处理数据的状态。状态用于决定从列表中删除,可以是开头、中间或结尾。该列表有时甚至可能根本没有任何数据,或者可能有多个节点要删除。

struct data
{
    bool status;
    char other_info[20];
    struct data *next;
};

我尝试了以下代码

struct data* delete_nodes(struct data *head)
{
    struct data* first = NULL, *prev = NULL, *temp = NULL;
    first = head;
    temp = head;
    prev = head;
    do
    {
        //prev = temp;

        if (temp != NULL && temp->next == head)
        {
            head->next = NULL;
            free(temp);
            head = NULL;
            return head;
        }

        if (temp != NULL && temp->status == true)
        {
            //temp = prev;
            prev->next = temp->next;
            free(temp);
            temp = prev->next;

        }
        else if(temp != NULL)
            temp = temp->next;
        if (temp == NULL)
            return head;
    } while (temp != NULL && first != temp);
    head = temp;
    return head;
}

现在,将数据推送到其中可以正常工作。如果只有一个节点,删除也可以正常工作。但是当有多个节点被删除时,它会崩溃。

delete_nodes() 函数由一个线程调用,该线程处理数据(如果有)并调用delete_nodes()

【问题讨论】:

  • delete_nodes() 是否删除除头部以外的所有节点?
  • 它应该删除任何节点,只要它的'status'是'true'
  • 如果状态为真,包括头部,对吧?
  • 是的,没错。

标签: c circular-list


【解决方案1】:

这个代码块

    if (temp != NULL && temp->status == true)
    {
        //temp = prev;
        prev->next = temp->next;
        free(temp);
        temp = prev->next;

    }

在进行第一次迭代时肯定是错误的。

在第一次迭代中,prevtemp 都与 head 相同。所以prev 指向与你free-ing 相同的内存。

考虑放弃对NULL 的所有检查,只在开始时进行检查,即

struct data* delete_nodes(struct data *head)
{
    if (head == NULL) return NULL;
    // Hereafter no further checks for NULL is needed

一个完整的函数可能如下所示:

struct data* delete_nodes(struct data *head)
{
    if (head == NULL) return NULL;

    struct data *prev = NULL;
    struct data *temp = head;
    struct data *first = head;

    do
    {
        struct data *next = temp->next;
        if (temp->status)
        {
            if (prev == NULL)
            {
                // Delete head element
                head = temp->next;
            }
            else
            {
                // Delete middle element
                prev->next = temp->next;
            }
            free(temp);
        } 
        else 
        {
            prev = temp;
        }
        temp = next;
    } while (temp != first);

    if (prev == NULL)
    {
         // List is empty
         return NULL;
    }
    return head;
}

【讨论】:

【解决方案2】:

以下语句导致问题

prev->next = temp->next; // what is prev here ?

应该是

if (temp != NULL && temp->next !=NULL && temp->status == true) {
        prev = temp;//current node which you want to delete 
        temp->next = prev->next;//this statement should be done before next statement..current node next should be prev node next
        prev->next = temp->next;//
        free(temp);
        temp = prev->next;
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多