Home > OS >  Linked List insertion using for loop in separate function
Linked List insertion using for loop in separate function

Time:02-26

I am learning how to program in C , and have looked at linked lists. I have found many code snippets to get me started.

The code I am playing with is from studytonight. I understand how to insert nodes into a list. But what if I want to create a linked list and fill x-many nodes at once in a loop? The for loop in my main() works fine, but when I try turning it into a function, such as arrayToList(), I am running into problems.

The function would simply use the entries of an array and turn them into the data (like an index) and a second value stored in the node. Obviously, the function needs to return a list to continue any manipulation, like deleting or replacing, etc, but also needs to receive a list as a parameter as the created list inside won't exist outside this function. The call to traverse the list inside the for loop is just to highlight that inside the function that list isn't empty.

I am a little lost as to make the function work, and would appreciate any help regarding a method to iteratively add x-many at once nodes to a linked list. I hope I have explained my problem well enough.

#include <iostream>
#include <stdlib.h>
using namespace std;
struct node
{
    int data;         // Data
    node *prev;      // A reference to the previous node
    node *next;     // A reference to the next node
    double x;
};

class Doubly_Linked_List
{
    node *front;      // points to first node of list
    node *end;       // points to first las of list
    public:
    Doubly_Linked_List()
    {
        front = NULL;
        end = NULL;
    }
    void add_front(int, double );
    void forward_traverse();
    void arrayToList(int[], int);

};

void Doubly_Linked_List :: add_front(int d, double x)
{
    // Creating new node
    node *temp;
    temp = new node();
    temp->data = d;
    temp->x = x;
    temp->prev = NULL;
    temp->next = front;

    // List is empty
    if(front == NULL)
        end = temp;
        
    else
        front->prev = temp;
        
    front = temp;
}

void Doubly_Linked_List :: forward_traverse()
{
    node *trav;
    trav = front;
    while(trav != NULL)
    {
        cout<<trav->data<<" (" << trav->x << " )" << endl;
        trav = trav->next;
    }
}

void Doubly_Linked_List :: arrayToList(int arr[], int n)
{
   Doubly_Linked_List list;
   for(int i=n-1; i>=0;i--)
   {
       cout << i << endl;
       list.add_front(arr[i], arr[i]);
       list.forward_traverse();
   }
}

int main()
{
    Doubly_Linked_List list;
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
//    for (int i= 1; i< 10; i  )
//    {
//        list.add_front(i, i*2);
//    }
    list.arrayToList(arr, n);
    cout << "after filling arrayList " << endl;
    list.forward_traverse();
}

CodePudding user response:

For starters the function should be declared like

void arrayToList( const int[], size_t );

and the function can be defined the following way if to take into account this commented statement in main

//        list.add_front(i, i*2);

void Doubly_Linked_List :: arrayToList( const int arr[], size_t n )
{
    while ( front )
    {
        node *current = front;
        front = front->next;
        delete current;
    }
    end = nullptr;

    for ( size_t i = n; i != 0; i-- )
    {
        add_front( arr[i-1], 2 * arr[i-1] );
    }
}

Though it would be better to declare the function at least like

void arrayToList( const std::pair<int, double>[], size_t );

CodePudding user response:

Your arrayToList() is creating and filling a local Doubly_Linked_List object named list, which is a separate object from the list in main(). Creating a local object is fine (it is good for exception safety), but arrayToList() is then discarding that local object and not assigning its data to the object that arrayToList() was actually called on. That is why your call to forward_traverse() in main() does not see anything changed.

Try this instead:

#include <utility>

void Doubly_Linked_List :: arrayToList(int arr[], int n)
{
   Doubly_Linked_List list;
   for(int i=n-1; i>=0;i--) {
       list.add_front(i, arr[i]);
   }

   // add this
   std::swap(front, list.front);
   std::swap(end, list.end);
}

Otherwise, get rid of the local list and modify the data in this instead:

void Doubly_Linked_List :: arrayToList(int arr[], int n)
{
   // optional: clear the called-on object first, if needed...
   // clear(); // <-- add this method to Doubly_Linked_List...

   for(int i=n-1; i>=0;i--) {
       add_front(i, arr[i]);
   }
}

Otherwise, change arrayToList() to be static, and then have it return a new Doubly_Linked_List object (just make sure you also implement a copy constructor, copy assignment operator, and destructor, per the Rule of 3/5/0):

class Doubly_Linked_List
{
...
    // implement these!
    ~Doubly_Linked_List();
    Doubly_Linked_List(const Doubly_Linked_List &);
    Doubly_Linked_List& operator=(const Doubly_Linked_List &);

    // and change this
    static Doubly_Linked_List arrayToList(int[], int);
...
};

Doubly_Linked_List Doubly_Linked_List :: arrayToList(int arr[], int n)
{
   Doubly_Linked_List list;
   for(int i=n-1; i>=0;i--) {
       list.add_front(i, arr[i]);
   }
   return list;
}

int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    Doubly_Linked_List list = Doubly_Linked_List::arrayToList(arr, n);
    cout << "after filling arrayList " << endl;
    list.forward_traverse();
}
  • Related