Я не могу удалить все узлы из связанного списка

#c #nodes #singly-linked-list

#c #узлы #single-linked-list

Вопрос:

Я работаю над школьным проектом, который посвящен работе с одним связанным списком. Я застрял на несколько часов, и я действительно не знаю, что делать. По сути, моя задача — удалить узлы из связанного списка.

Это то, что я храню в узлах в настоящее время:

 1. Jozef Maly 7502110011 1178.88
2. Maria Krasna 6251034526 1636.90
3. Milan Vesely 9512157831 1835.20
4. asd fgh 9862111680 2000.00
5. lol pop 9862111680 2000.00
  

Это мой текущий результат:

 Deleted 2 nodes.                           //not really
1. Jozef Maly muz 11.02.1975 1178.88
2. Maria Krasna zena 03.01.1962 1636.90
3. Milan Vesely muz 15.12.1995 1835.20
4. lol pop zena 11.12.1998 2000.00
  

Вот как должен выглядеть мой результат:

 Deleted 2 nodes.
1. Jozef Maly 7502110011 1178.88
2. Maria Krasna 6251034526 1636.90
3. Milan Vesely 9512157831 1835.20
  

Вот мой код:

 void overRC(struct list *z) {
    int arr[10], notvalidarr[1000];
    int notvalid = 0, x = 0, i = 0, j = 0, k = 0, day, month, year, number;
    int len = length(z); //this function returns the number of nodes

    struct data *temp;
    temp = z->first; //z -> first is the head
    while (temp != NULL) {
        i  ;  
        number = temp->ID / 10000;
        for (int j = 0; j < 6; j  ) {
            arr[j] = number % 10;
            number /= 10;
        }
        day = 10 * arr[1]   arr[0];
        month = 10 * arr[3]   arr[2];
        year = 1900   10 * arr[5]   arr[4];

        if (temp->ID % 11 != 0 || month <= 0 || month > 12 amp;amp; month < 51 || month > 62 || month == 2 amp;amp; day > 29 || month <= 7 amp;amp; month % 2 == 1 amp;amp; day > 31  || || month <= 7 amp;amp; month % 2 == 0 amp;amp; day > 30 || month >= 8 amp;amp; month % 2 == 0 amp;amp; day > 31 || month >= 8 amp;amp; month % 2 == 1 amp;amp; day > 30) {
            notvalidarr[x  ] = i; //i store the positions in this array: 4, 5
        }
        day = 0;
        month = 0;
        year = 0;
        temp = temp->next;
    }

    for (j = 0; j < x; j  ) {
        deleteNode(amp;z->first, notvalidarr[j]);
        notvalid  ;
    }
    printf("Deleted %d nodesn", notvalid);  //it says it deleted 2
}

void deleteNode(struct data **head_ref, int position) { 
    if (*head_ref == NULL) 
        return; 

    struct data *temp = *head_ref; 

    if (position == 1) { 
        *head_ref = temp->next;  
        free(temp);              
        return; 
    } 

    for (int i = 1; i < position - 1; i  ) 
        temp = temp->next; 

    if (temp == NULL || temp->next == NULL) 
        return; 

    struct data *next = temp->next->next; 

    free(temp->next);
    temp->next = next; 
}
  

Ответ №1:

Код не компилируется, потому что тест для notvalidarr имеет синтаксическую ошибку: || следует быть || . Вы должны упростить этот тест с помощью массива максимальных значений для дней в месяцах.

Существует потенциальная проблема в deleteNode функции, если position она слишком велика, потому что вы не проверяете, что temp это не null перед оценкой temp = temp->next;

В вызывающем коде есть еще одна проблема deleteNode : массив удаляемых узлов должен быть отсканирован от самой высокой позиции до самой низкой, в противном случае позиции будут неверными после удаления узла.

Вот исправленная и упрощенная версия:

 void overRC(struct list *z) {
    static int mdays[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int deleted = 0;
    struct data **linkp = amp;z->first;
    struct data *temp;

    while ((temp = *linkp) != NULL) {
        int number = temp->ID / 10000;
        int day = number % 100;
        int month = number / 100 % 100;
        int year = 1900   number / 10000 % 100;

        if (temp->ID % 11 != 0 ||
            month <= 0 || month > 12 ||
            day <= 0 || day > mdays[month] ||
            (month == 2 amp;amp; day == 29 amp;amp; (year == 1900 || year % 4 != 0))) {
            *linkp = temp->next;
            free(temp);
            deleted  ;
        } else {
            linkp = amp;temp->next;
        }
    }
    printf("Deleted %d nodesn", deleted);
}
  

Комментарии:

1. Да, пока я переводил текст, я допустил несколько ошибок, поэтому в коде была синтаксическая ошибка. После нескольких изменений все работает нормально, спасибо за вашу помощь =)