Home > front end >  Deleting all nodes smaller than x in singly linked list in c
Deleting all nodes smaller than x in singly linked list in c

Time:02-25

I making a program that the lets the user enter countless integers until the number 0 is entered, then display and sort it from smallest to largest. Code:

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
    int data;
    struct node *ptr;
} node;

node * insert(node *head, int num)
{
    node *temp = malloc(sizeof(node));
    temp->data = num;

    if (head == NULL || head->data > num)
    {
        temp->ptr = head;
        head = temp;
    }
    else
    {
        node *current = head;
        while ((current->ptr != NULL) && !(num < current->ptr->data))

        {
            current = current->ptr;
        }

        temp->ptr = current->ptr;
        current->ptr = temp;
    }

    return head;
}

void free_list(node *head) {
    node *prev = head;
    node *cur = head;
    while(cur) {
        prev = cur;
        cur = prev->ptr;
        free(prev);
    }
}

int main(){
    int num, min;
    node *head, *p;
    head = NULL;

    do {
        printf("Enter a number: ");
        scanf("%d",&num);
        if(num) {
            head = insert(head, num);
            for ( p = head; p != NULL; p = p->ptr )
            {
                printf("%d->", p->data);
            }
            puts( "NULL " );
        }
    } while(num);

    p = head;
    printf("\nThe entered numbers are:\n");

    while(p) {
        printf("%d->", p->data);
        p = p->ptr;
    }
    free_list(head);
    printf("NULL\n");

    printf("\nEnter minimum: ");
    scanf("%d", & min);

    return 0;
}

I however need then to delete all the numbers that are smaller than a specified node, i.e. minimum. Then display the list after the deletion, and how many nodes were deleted.

Finally the average/arithmetic mean of the old list before deletion, and the new list after the deletion to be calculated and displayed.

All in all, the output should look like something like this:

Enter number: 5
5->NULL
Enter number: 6
5->6->NULL
Enter number: 3
3->5->6->NULL
Enter number: 9
3->5->6->9->NULL
Enter number: 4
3->4->5->6->9->NULL
Enter number: 0

Entered numbers :
3->4->5->6->9->NULL

Enter minimum: 6
3->4->5->6->9->NULL
4->5->6->9->NULL
5->6->9->NULL
6->9->NULL

Deleted nodes: 3

Old average: 5.4
New average: 7.5

Can anyone help? Thanks in advance...

CodePudding user response:

Taking into account this output

Enter minimum: 6
3->4->5->6->9->NULL
4->5->6->9->NULL
5->6->9->NULL
6->9->NULL

it seems that the function that removes a node from the list should remove at most one node in each its call.

If so then the function can look for example the following way

int delete_if_less( node **head, int data )
{
    while ( *head != NULL && !( ( *head )->data < data ) )
    {
        head = &( *head )->ptr;
    }

    int success = *head != NULL

    if ( success )
    {
        node *temp = *head;
        *head = ( *head )->ptr;
        free( temp );
    }

    return success;
}

And the function can be called in a loop provided that the variable num contains the target value for example the following way

size_t n = 0;
do
{            
    for ( p = head; p != NULL; p = p->ptr )
    {
        printf("%d->", p->data);
    }
    puts( "NULL" );
} while ( delete_if_less( &head, num ) &&   n );

After this do-while loop the variable n will contain the number of removed nodes in the list.

If you want to remove all nodes that satisfy the condition then the function can look the following way

size_t delete_if_less( node **head, int data )
{
    size_t n = 0;

    while ( *head != NULL )
    {
        if ( ( *head )->data < data )
        {
            node *temp = *head;
            *head = ( *head )->ptr;
            free( temp );
              n;
        }
        else
        {
            head = &( *head )->ptr;
        }
    }

    return n;
}

and the function can be called like

size_t n = delete_if_less( &head, num );

if ( n != 0 ) printf( "There are deleted %zu nodes.\n", n );

Another way to define the function is the following

node * delete_if_less( node *head, int data )
{
    while ( head != NULL && head->data < data )
    {
        node *temp = head;
        head = head->ptr;
        free( temp );
    }

    if ( head != NULL )
    {
        for ( node *current = head; current->ptr != NULL; )
        {  
            if ( current->ptr->data < data )
            {
                node *temp = current->ptr;
                current->ptr = current->ptr->ptr;
                free( temp );
            } 
            else
            {
                current = current->ptr;
            }
        }
    }

    return head;
}

And the function is called like

head = delete_if_less( head, num );
  • Related