Home > Net >  Couldn't create a linked list
Couldn't create a linked list

Time:05-06

My create function is not creating a linked list.

I can't seem to figure out the problem here. The code runs but I don't get any output.

Can anyone figure out what mistake did I make here?

 class Node
 {
     public:
     int data;
     Node *next;
 } *head=NULL;
 void create(int a[])
 {
     int i;
     Node *t,*last;
     Node *head=new Node();
     head->data=a[0];
     head->next=NULL;
     last=head;
     for(i=1;i<6;i  )
     {
         Node *t=new Node();
         t->data=a[i];
         t->next=NULL;
         last->next=t;
         last=t;
     }
 }
 void display(Node *p)
 {
     while(p!=NULL)
     {
         cout<<p->data<<"->";
         p=p->next;
     }
 }
 int main()
 {
     int a[]={2,3,4,5,6,7};
     create(a);
     display(head);
 
     return 0;
 }

CodePudding user response:

You're trying to use head, but haven't initialized it.

You're defining it here:

class Node {
    public:
    int data;
    Node *next;
} *head = NULL;

But then in create, you're creating a new variable head, so the one defined above doesn't get initialized.

void create(int a[]) {
    int i;
    Node *t, *last;

    // Note: Here, you're defining a local variable `head`
    Node *head = new Node();
    head->data = a[0];
    head->next = NULL;
    last = head;
    for(i=1; i<6; i  ) {
        Node *t = new Node();
        t->data = a[i];
        t->next = NULL;
        last->next = t;
        last = t;
    }
 }

So when you call display in main, you're doing so on a null-pointer

display(head);

CodePudding user response:

Your main problem is that you do not have a linked list at all. You have just nodes.

Then, you define a global variable of type "Node*" with the name "head" and initialize that with "NULL"

But, in your create function, youd define new, different "Node*" variables. And especially a different "head".

Everything that is defined in yor create function, will go out of scope after leaving the function. It vanishes and just leaves memory holes, because you never deleted any memory that you newed.

And in you main, you call the "create" function, which does not change the global head at all. So, nothing will happen hear . . .

You need to read more about linked list. Especially about nodes which are a part of a linked list. But the node itself is not the linked list. It is just a node . . .

For learning purposes I add a demo linked list implementation below. You may have a look for getting better understanding.

#include <iostream>
#include <iterator>
#include <initializer_list>
#include <algorithm>

// Very simple implementation of a forward list
template <class T>
class SinglyLinkedList {

    // The node
    struct Node {
        T data{};     // Data. Would normally be a templated argument
        Node* next{};   // And the pointer to the next node

        Node(const T& i, Node* n = nullptr) : data(i), next(n) {}; // Simple constructor to set a value and next pointer
    };

    Node* head{};       // This is the start of the list
    // It would be advisable to have a tail pointer. We use the more inefficient approach here
    Node* getLast() const { Node* n{ head }; while (n and n->next) n = n->next; return n; }

public:
    // Constructor / Destructor --------------------------------------------------------------------------------------------------------
    ~SinglyLinkedList() { clear(); }

    // Default constuctor
    SinglyLinkedList() {}   // Default

    // From an initialization list
    SinglyLinkedList(const std::initializer_list<T>& il) { clear();  for (const T& i : il) push_back(i); } // From initializer list

    // Copy constructor
    SinglyLinkedList(const SinglyLinkedList& other) { clear(); for (const T& i : other) push_back(i); }

    // Move constructor. Will steal the elements from the other 
    SinglyLinkedList(SinglyLinkedList&& other) noexcept { head = other.head; other.head = nullptr;}

    // Assignment operator
    SinglyLinkedList& operator = (const SinglyLinkedList& other) { clear(); for (const T& i : other) push_back(i); }

    // Move assignment operator 
    SinglyLinkedList& operator = (SinglyLinkedList&& other) { head = other.head; other.head = nullptr; }

    // Housekeeping --------------------------------------------------------------------------------------------------------------
    void clear() { Node* tmp{ head }; while (tmp) { Node* toDelete{ tmp }; tmp = tmp->next; delete toDelete; } head = nullptr; }
    int empty() const { return head == nullptr; }
    int size() const { int k{}; Node* n{ head }; while (n) {   k; n = n->next; } return k; }

    // Modify content --------------------------------------------------------------------------------------------------------------
    void push_front(const T& i) { Node* n = new Node(i); n->next = head; head = n; };
    void push_back(const T& i) { Node* n = new Node(i); Node* l = getLast(); if (l) l->next = n; else head = n; }
    void pop_front() { if (head) { Node* tmp = head->next; delete head; head = tmp; } }
    void pop_back() { // This is a little bit more difficult in a singly linked list
        if (head) {
            Node* n{ head }, * previous{};
            while (n and n->next) {
                previous = n;
                n = n->next;
            }
            delete n;
            if (previous)
                previous->next = nullptr;
            else
                head->next = nullptr;
        }
    }

    // Access elements --------------------------------------------------------------------------------
    T& front() const { return head ? head->data : 0; };
    T back() const { Node* n = getLast(); return n ? n->data : 0; }

    // Add iterator properties to class ---------------------------------------------------------------
    struct iterator {                           // Local class for iterator
        Node* iter{};                           // Iterator is basically a pointer to the node
        Node* head{};

        // Define alias names necessary for the iterator functionality
        using iterator_category = std::bidirectional_iterator_tag;
        using difference_type = std::ptrdiff_t;
        using value_type = T;
        using pointer = T*;
        using reference = T&;

        // Constructor
        iterator() {}
        iterator(Node* n, Node* h) : iter(n), head(h) {}

        // Dereferencing
        reference operator *() const { return iter->data; }
        pointer operator ->() const { return &iter->data; }

        // Aithmetic operations
        iterator& operator   () { if (iter) iter = iter->next; return *this; }
        iterator operator   (int) { iterator temp{ *this };   * this; return temp; }

        // Clumsy subtratcion
        iterator& operator --() { Node* tmp = head; while (tmp and tmp->next != this->iter) tmp = tmp->next; iter = tmp;  return *this; }
        iterator operator --(int) { iterator temp{ *this }; --* this; return temp; }

        iterator operator  (const difference_type& n) const {
            iterator temp{ *this };  difference_type k{ n }; if (k > 0) while (k--)  temp; else while (k  )--temp; return temp;
        }
        iterator operator  =(const difference_type& n) {
            difference_type k{ n }; if (k > 0) while (k--)  * this; else while (k  )--* this; return *this;
        };
        iterator operator -(const difference_type& n) const {
            iterator temp{ *this };  difference_type k{ n }; if (k > 0) while (k--)--temp; else while (k  )  temp; return temp;
        }
        iterator operator -=(const difference_type& n) {
            difference_type k{ n }; if (k > 0) while (k--)--* this; else while (k  )  * this; return *this;
        };

        // Comparison
        bool operator != (const iterator& other) const { return iter != other.iter; }
        bool operator == (const iterator& other) const { return iter == other.iter; }
        bool operator < (const iterator& other) const { return other.iter - iter < 0; };
        bool operator <= (const iterator& other) const { return other.iter - iter <= 0; };
        bool operator > (const iterator& other) const { return other.iter - iter > 0; };
        bool operator >= (const iterator& other) const { return other.iter - iter >= 0; };

        // Difference. Also complicated, because no random access
        difference_type operator-(const iterator& other) const {
            difference_type result{};

            int indexThis{ -1 }, indexOther{ -1 }, index{};

            Node* nptr = head;
            while (nptr != nullptr) {
                if (nptr == iter)
                    indexThis = index;
                if (nptr == other.iter)
                    indexOther = index;
                nptr = nptr->next;
                  index;
            }
            if (nptr == iter)
                indexThis = index;
            if (nptr == other.iter)
                indexOther = index;
            if (indexThis >= 0 and indexOther >= 0)
                result = indexThis - indexOther;
            return result;
        }
    };

    // Begin and end function to initialize an iterator
    iterator begin() const { return iterator(head, head); }
    iterator end() const { return iterator(nullptr, head); }

    // Functions typcical for forward lists ----------------------------------------------------------------------
    // Easy, becuase we can operate form the current iterator and do not need the "previous" element
    iterator insertAfter(iterator& pos, const T& i) {
        iterator result(nullptr, head);
        if (pos.iter and pos.iter->next) {
            Node* n = new Node(i, pos.iter->next);
            pos.iter->next = n;
            result.iter = n;
        }
        return result;
    }
    iterator eraseAfter(iterator& pos) {
        iterator result(nullptr, head);
        if (pos.iter and pos.iter->next) {
            Node* tmp = pos.iter->next->next;
            delete pos.iter->next;
            pos.iter->next = tmp;
            result.iter = pos.iter->next;
        }
        return result;
    }
};
// Test/Driver Code
int main() {

    // Example for initilizer list
    SinglyLinkedList<int> sllbase{ 5,6,7,8,9,10,11,12,13,14,15 };
    // Show move constructor
    SinglyLinkedList<int> sll(std::move(sllbase));

    // Add some values in the front
    sll.push_front(4);
    sll.push_front(3);
    sll.push_front(2);
    sll.push_front(1);

    // Delete 1st element (Number 1)
    sll.pop_front();
    // Delete last element
    sll.pop_back();

    // Use a std::algorithm on our custom linked list. Works because we have an interator
    SinglyLinkedList<int>::iterator iter = std::find(sll.begin(), sll.end(), 8);
      iter;
    --iter;

    // Now add an element after 8
    iter = sll.insertAfter(iter, 88);
    // And delete the 9
    iter = sll.eraseAfter(iter);

    std::cout << "\n\nDelta between end and begin: " << (sll.end() - sll.begin()) << "\n\n";

    // Use range based for loop. Works because, we have iterators
    for (int i : sll)
        std::cout << i << ' ';

    // Reverse Output
    std::cout << "\n\n";
    std::reverse_iterator<SinglyLinkedList<int>::iterator> riter = std::make_reverse_iterator(sll.end());
    std::reverse_iterator<SinglyLinkedList<int>::iterator> riterEnd = std::make_reverse_iterator(sll.begin());

    for (; riter != riterEnd;   riter)
        std::cout << *riter << ' ';
    std::cout << "\n\n";

    return 0;
}

  • Related