Home > OS >  C Single linked list problem deleting node
C Single linked list problem deleting node

Time:10-12

I have written this code for deleting all nodes which are divisible by 9. But when I try to input two consecutive numbers that are divisible by 9 only of them is deleted.

void deletebydivisable(){
    Node *currentNode = head;

    while (currentNode!=NULL){

        if(currentNode->nextNodeAddress->data % 9 == 0){
            Node *todelted = currentNode->nextNodeAddress;
            currentNode->nextNodeAddress = todelted->nextNodeAddress;
            delete(todelted);
        }
        currentNode = currentNode->nextNodeAddress;
    }
}

CodePudding user response:

Assuming if you have linked list as 9 -> 18 -> NULL

In the first Iteration currentNode points to 9

As per your logic it will delete currentNode->nextNodeAddress which is 18 and update linked list: 9 -> NULL

and due to currentNode = currentNode->nextNodeAddress; in your code,
currentNode will also get updated to NULL

So the loop ends as the while condition is false and 9 never gets deleted! You need to improve your code and dry run like this to understand better!

CodePudding user response:

Your logic is wrong, for several reasons:

  • you not taking into account that the currentNode->nextNodeAddress field will be NULL when currentNode is pointing at the last node in the list. You should be deleting the currentNode, not its nextNodeAddress.

  • you are not taking into account the possibility that the 1st node in the list may be divisible by 9, in which case you would have to update the head pointer to point at the 2nd node in the list.

  • when deleting a node, you are not updating the nextNodeAddress field of the previous node to no longer point at the deleted node but to now point at the next node in the list.

Try this instead:

void deletebydivisable(){
    Node *currentNode = head;
    Node *previousNode = NULL;

    while (currentNode != NULL) {
        Node *nextNode = currentNode->nextNodeAddress;
        if ((currentNode->data % 9) == 0) {
            if (head == currentNode) {
                head = nextNode;
            }
            else {
                previousNode->nextNodeAddress = nextNode;
            }
            delete currentNode;
        }
        else {
            previousNode = currentNode;
        }
        currentNode = nextNode;
    }
}

Which can be simplified slightly by using a pointer-to-pointer to eliminate the innermost if-else block, eg:

void deletebydivisable(){
    Node *currentNode = head;
    Node **previousNode = &head;

    while (currentNode != NULL) {
        if ((currentNode->data % 9) == 0) {
            *previousNode = currentNode->nextNodeAddress;
            delete currentNode;
        }
        else {
            previousNode = &(currentNode->nextNodeAddress);
        }
        currentNode = *previousNode;
    }
}
  • Related