Home > front end >  Delete in Linked List
Delete in Linked List

Time:02-03

So I revisited double linked list, found I'm really stupid, and can't figure things out even when I narrowed down problem to delete operator. I'm still playing around with templates, so maybe there's something wrong with templates as well. Print works fine without deleting a node. Please tell me what's wrong.

Result of code run is just that it doesn't print anything.

template<typename T>
class DoubleLinkedList
{
    struct Node;
    Node *head;
    Node *tail;
public:
    DoubleLinkedList(Node *head = nullptr) : head(head) {
        if (head == nullptr) {
            tail = nullptr;
            return;
        }
        Node *tmp;
        for (tmp = head; tmp->next != nullptr; tmp = tmp->next);
        tail = tmp;
    }

    void addfront(T val) {
        Node *newnode = new Node(val, head);
        if (head == nullptr) {
            head = tail = newnode;
            return;
        }
        newnode->next = head;
        head->prev = newnode;
        head = newnode;
    }
    void addend(T val) {
        Node *newnode = new Node(val, nullptr, tail); 
        // There's probably a very obvious reason here, but my brain is busted and can't figure out 
        // what's wrong 
        if (head == nullptr) {
            head = tail = newnode;
            return;
        }
        tail->next = newnode;
        newnode->prev = tail;
        tail = newnode;
        
    }

    void del(T val) {
    
        for (Node *tmp = head; tmp != nullptr; tmp = tmp->next) {
            if (tmp->value == val) {
                if (tmp != head)
                    tmp->prev->next = tmp->next;
                else 
                    head = tmp->next;
                if (tmp->next != nullptr)
                    tmp->next->prev = tmp->prev;
                else
                    tail = tmp->prev;
                // print();
                delete tmp;  // delete not working, even when delete function is empty with just 
                             // delete head, it's a memory issue that my head can't wrap around
                break;
            }
        }
    }
    void print()
    {
        for (Node *tmp = head; tmp != nullptr; tmp = tmp->next)
            std::cout << tmp->value << ", ";
    }
    ~DoubleLinkedList() {
        Node *tmp;
        for (tmp = head; tmp->next != nullptr; tmp = tmp->next) 
            delete tmp->prev;
        delete tmp->prev;
        delete tmp;
    }
};
template<typename T>
struct DoubleLinkedList<T>::Node : DoubleLinkedList<T>
{
    T value;
    Node *prev;
    Node *next;

    Node(T val, Node *next = nullptr, Node *prev = nullptr) : 
    value(val), prev(prev), next(next) {}
};
int main()
{
    DoubleLinkedList<int> numlist;
    for (int i = 0; i < 10; i  )
        numlist.addend(i);
    numlist.del(0);
    numlist.print();
}

CodePudding user response:

The ~DoubleLinkedList() logic is all wrong. When the list is empty, head is nullptr, so accessing tmp->next in the loop is undefined behavior. And the way you are deleting nodes is just weird in general. It should look more like this instead:

~DoubleLinkedList() {
    Node *tmp, *next;
    for (tmp = head; tmp != nullptr; tmp = next) {
        next = tmp->next;
        delete tmp;
    }
}

The reason this was causing problems is because you have DoubleLinkedList::Node deriving from DoubleLinkedList, so delete'ing a node was calling the invalid ~DoubleLinkedList() destructor. There is no good reason for Node to derive from DoubleLinkedList at all.

After fixing those 2 things, the rest of the code works fine for me, especially the del() call:

#include <iostream>
using namespace std;
 
template<typename T>
class DoubleLinkedList
{
    struct Node
    {
        T value;
        Node *prev;
        Node *next;

        Node(T val, Node *next = nullptr, Node *prev = nullptr) : 
            value(val), prev(prev), next(next) {}
    };

    Node *head;
    Node *tail;
public:
    DoubleLinkedList(Node *head = nullptr) : head(head) {
        if (head == nullptr) {
            tail = nullptr;
            return;
        }
        Node *tmp;
        for (tmp = head; tmp->next != nullptr; tmp = tmp->next);
        tail = tmp;
    }
 
    void addfront(T val) {
        Node *newnode = new Node(val, head);
        if (head == nullptr) {
            head = tail = newnode;
            return;
        }
        newnode->next = head;
        head->prev = newnode;
        head = newnode;
    }
 
    void addend(T val) {
        Node *newnode = new Node(val, nullptr, tail); 
        if (head == nullptr) {
            head = tail = newnode;
            return;
        }
        tail->next = newnode;
        newnode->prev = tail;
        tail = newnode;
    }

    void del(T val) {
        for (Node *tmp = head; tmp != nullptr; tmp = tmp->next) {
            if (tmp->value == val) {
                if (tmp != head)
                    tmp->prev->next = tmp->next;
                else 
                    head = tmp->next;
                if (tmp->next != nullptr)
                    tmp->next->prev = tmp->prev;
                else
                    tail = tmp->prev;
                // print();
                delete tmp;
                break;
            }
        }
    }

    void print()
    {
        for (Node *tmp = head; tmp != nullptr; tmp = tmp->next)
            std::cout << tmp->value << ", ";
        std::cout << "\n";
    }

    ~DoubleLinkedList() {
        Node *tmp, *next;
        for (tmp = head; tmp != nullptr; tmp = next) {
            next = tmp->next;
            delete tmp;
        }
    }
};

int main()
{
    DoubleLinkedList<int> numlist;
    for (int i = 0; i < 10; i  )
        numlist.addend(i);
    numlist.print();
    numlist.del(0);
    numlist.print();
}

Online Demo

  •  Tags:  
  • Related