Home > Enterprise >  I created a LinkedList and i am trying to remove the element . it removes the element only onces rat
I created a LinkedList and i am trying to remove the element . it removes the element only onces rat

Time:01-12

#include <iostream>
using namespace std; 

class Node {
    public :
        int val;
        Node* next;

        Node(int data) {
            this -> val = data;
            this -> next = NULL;
        }
};


void insertAtTail(Node* &tail, int data) {
    Node* temp = new Node(data);
    tail -> next = temp;
    tail = temp;
}

void print (Node* head) {
    while(head != NULL) {
        cout << head -> val << " ";
        head = head -> next;
    }
    cout << endl;
}

Node* removeElement(Node* head, int val) {
    if(head -> val == val) {
        while(head -> val == val) {
            head = head -> next;
        }
        return head;
    }

    else {
        Node* prev = NULL;
        Node* curr = head;
        while(curr -> next != NULL) {
            prev = curr;
            curr = curr -> next;
            if(curr -> val == val) {
                prev -> next = curr -> next;
            }
            //cout << prev -> val << " ";  
        }
        
    return head;
    }
}
int main () {
    Node* node1 = new Node(1);
    Node* head = node1;
    Node* tail = node1;

    insertAtTail(tail, 1);
    insertAtTail(tail, 1);
    insertAtTail(tail, 3);
    insertAtTail(tail, 3);
    insertAtTail(tail, 5);
    
    print(removeElement(head, 3));
}
  1. problem -

In this i have passed element to tail in linkedlist and then i am trying to remove specifc element using removeElement() what it does it removes only one element that is matched and leaving the other remaing matching element

Image

I want to remove all the element its matches.

CodePudding user response:

Nothing beats drawing.
You should use pen(cil) and paper, but here is an ASCII version of what you're doing:


 p is null
 
head->1->1->3->3->5
 ^
 c

prev = curr;

 p
 v
head->1->1->3->3->5
 ^
 c

curr = curr->next

 p
 v
head->1->1->3->3->5
      ^
      c

prev = curr;

      p
      v
head->1->1->3->3->5
      ^
      c

curr = curr->next

      p
      v
head->1->1->3->3->5
         ^
         c

prev = curr;

         p
         v
head->1->1->3->3->5
         ^
         c

curr = curr->next

         p
         v
head->1->1->3->3->5
            ^
            c

if(curr -> val == val) {
    prev -> next = curr -> next;
}

         p  ---- 
         v |    v
head->1->1-  3->3->5
             ^
             c 

(Note that this detaches 'curr' from the list.)             

prev = curr;

            ---- 
           |    v
head->1->1-  3->3->5
             ^
             c
             p

(And 'prev' now points to the detached node.)

curr = curr->next

            ---- 
           |    v
head->1->1-  3->3->5
             ^  ^
             p  c



if(curr -> val == val) {
    prev -> next = curr -> next;
}

            ------- 
           |       v
head->1->1-  3-    3->5
             ^ |   ^  ^
             p |   c  |
               |      |
                ------ 

(And this sets the 'next' pointer of a node that is no longer part of the list.)

prev = curr;

            ------- 
           |       v
head->1->1-  3-    3->5
               |   ^  ^
               |   c  |
               |   p  |
                ------ 

curr = curr->next


            -------   c
           |       v  v
head->1->1-  3-    3->5
               |   ^  ^
               |   p  |
               |      |
                ------ 

and curr->next is null.

Result:

            -------    
           |       v   
head->1->1-        3->5

Now use pen(cil) and paper and work out what the code should do, and then translate that into code.
(Hint: you need to do different things depending on whether you remove a node or not.)

CodePudding user response:

The implementation has some issues and will not work for many test cases. However, there is at least one major problem in the second while loop of the removeElement. I tried to solve it with minimal modifications for the specific test that you sent.

Replace it with the following code:

while(curr -> next != NULL) {
  if(curr -> val == val) {
    prev -> next = curr -> next;
    curr = prev -> next;
  }
  else {
    prev = curr;
    curr = curr -> next;
  }
  //cout << prev -> val << " ";  
}

CodePudding user response:

A lot of how you should deal with this depends on your real goal in writing the code. If you're planning to put this to real use, you probably don't want to write any of this. The standard library already has code for linked lists, and absent a reason to do otherwise, you normally want to use that.

    // intersperse '1' with other elements:
    std::forward_list<int> ints { 1, 3, 1, 3, 1, 5, 1 };

    // remove all the '1' elements:
    ints.remove(1);

    // print out the result:
    std::copy(ints.begin(), ints.end(),
        std::ostream_iterator<int>(std::cout, " "));

Result:

3 3 5

No muss, no fuss, no memory leaks. Better still, this is fairly easy to convert to (for example) an std::vector, since linked lists are only rarely a good idea anyway.

If this is for homework (or something like that) where implementing the linked list yourself is the whole point of the exercise, I'd start by wrapping the linked list up as a class with a few member functions, and the node hidden inside:

class list {

    class node {
        int value;
        node *next = nullptr;

        node(int value, node *next = nullptr) : value(value), next(next) {}
    };

    node *head;
    node *tail;

public:

    void insertHead(int newValue);
    void insertTail(int newValue);
    bool remove(int oldValue);
    void print() const;
};
  • Related