I'm working on a school project, which is about doing stuff with single linked list. I'm stuck for few hours now, and I don't really know what to do. Basically, my task is to delete nodes from the linked list.

This is what I store in the nodes currently:

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

This is my current result:

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

This is what my result should look like:

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

Here is my code:

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 && month < 51 || month > 62 || month == 2 && day > 29 || month <= 7 && month % 2 == 1 && day > 31  || || month <= 7 && month % 2 == 0 && day > 30 || month >= 8 && month % 2 == 0 && day > 31 || month >= 8 && month % 2 == 1 && 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(&z->first, notvalidarr[j]);
        notvalid++;
    }
    printf("Deleted %d nodes\n", 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 Answers

0
chqrlie On Best Solutions

The code does not compile because the test for notvalidarr has a syntax error: || followed be ||. You should simplify this test with an array of maximum values for days in months.

There is a potential problem in the deleteNode function if the position is too large because you do not test that temp is no null before evaluating temp = temp->next;

There is another problem in the code that calls deleteNode: the array of nodes to be removed should be scanned from the highest position to the lowest, otherwise the positions are incorrect after you remove a node.

Here is a corrected and simplified version:

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 = &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 && day == 29 && (year == 1900 || year % 4 != 0))) {
            *linkp = temp->next;
            free(temp);
            deleted++;
        } else {
            linkp = &temp->next;
        }
    }
    printf("Deleted %d nodes\n", deleted);
}