C++ data structures wrong output (linked lists) - c++

#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct node{
int size;
char* name;
node* next;
}node;
void insertnodes( node** arrayhead , int index , node* ptr){
index = index - 1 ;
while ( index--){
*arrayhead = (*arrayhead)->next;
}
(*arrayhead)->next = new node;
(*arrayhead)->next = ptr;
}
int main(){
int n = 4;
node *A[n] ;
for ( int i = 0 ; i < n ; i++){
A[i] = NULL ;
}
A[0] = new node;
A[0]->size = 10;
A[0]->name = new char;
A[0]->name = "gunna";
A[0]->next = NULL;
//cout << A[0]->name << endl;
node* ptr = new node ;
ptr->size = 10;
ptr->name = new char;
ptr->name = "param";
ptr->next = NULL;
insertnodes(&A[0] , 1 , ptr);
node* ptrr = new node ;
ptrr->size = 10;
ptrr->name = new char;
ptrr->name = "sidd";
ptrr->next = NULL;
insertnodes(&A[0] , 2 , ptrr);
cout << A[0]->name << endl;
cout << A[0]->next->name;
}
It should have to print "gunna" and "param" .
but it is giving "param" and "sidd" as output.
I don'nt know where i am going wrong . I have tried a lot of things but i am still confused
Pls help ...
I am using code blocks to compile this program ..

In your insertnodes() you are passing a double pointer node** arrayhead, thus, by dereferncing it later, you are overwriting the current value of next pointer, which will later cause memory leak in your program.
What you should do instead is create a temporary variable node* tmp which you will change when the index decreases. Then, you don't need to allocate a new node to the next pointer, because you already have a pointer you want to attach as next.
The fixed code would look like this:
void insertnodes(node** arrayhead, int index, node* ptr) {
index = index - 1;
node* tmp = *arrayhead;
while (index--) {
tmp = tmp->next;
}
tmp->next = ptr;
}
EDIT: This is completely useless:
int n = 4;
node *A[n] ;
for ( int i = 0 ; i < n ; i++){
A[i] = NULL ;
}
All you need to create a linked list is a single node (e.g. list's head).
But as this is a linked list, you don't need to pass index really. All you need is a head, over which you could iterate until you find node->next which will be NULL - this is the place you need to insert your new node at (this is how it's typically done).

Related

create linked list with for loop...why we should use l->next.....why we can just use l=t only to assigne the previous address of the node?

#include<iostream>
using std::cout;
struct node
{
int data;
node* next;
};
void Display(node* p)
{
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
int main()
{
node* t = new node{ 0 }, * head = t;
node* l = t;
for (size_t i = 1; i <= 5; i++)
{
t = new node;
t->data = i;
t->next = NULL;
l->next = t;
l = t;
}
Display(head);
return 0;
}
why we should use l->next=t ......is this a right way to fill a linked list throw a for loop or even copy items from an array or any source of data;
If you will write
l = t;
instead of
l->next = t;
l = t;
then the list will be broken because the data member next of the node pointed to by the pointer l will not point to the new node pointed to by the pointer t and will have the value NULL.
As a result you will have six separate nodes the data member next of which will be equal to NULL. So you will not have a linked list.

can not keep the head of a linked list unchanged

I am new at linked List. Recently I have tried to create a program which takes an array and its size as input. then it converts the array into a linked list and print elements. But the program is not working and I guess it is because the head pointer get changed. So, what I can do to keep the head node unchanged?
#include<bits/stdc++.h>
using namespace std ;
struct node
{
int data ;
node* link ;
};
node* create_linkedlist (int ara[] , int siz )
{
node* head = NULL ;
node* temp = new node() ;
temp->data = ara[0] ;
temp->link = NULL ;
head = temp ;
node* tmhead = head->link ;
node* temp2 ;
for(int i = 1 ; i < siz ; i++)
{
temp2 = new node() ;
temp2->data = ara[i] ;
temp2->link = NULL ;
while ( tmhead->link!= NULL)
{
tmhead = tmhead->link ;
}
tmhead->link = temp2 ;
}
return head ;
}
void printlist( node* h_ref )
{
while (h_ref != NULL)
{
printf("%d " , h_ref->data) ;
h_ref = h_ref->link ;
}
}
int main()
{
int siz ;
cin>> siz ;
int ara[siz + 2];
for(int i = 0 ; i < siz ; i++)
{
cin >> ara[i] ;
}
node* hd = create_linkedlist(ara , siz) ;
node* temp = hd ;
printlist(temp) ;
return 0 ;
}
For the second element (first iteration of loop) in create_linkedlist() function, tmhead is NULL and you are trying to de-reference it which will lead to a crash.
Change the line node* tmhead = head->link ; to node* tmhead = head; and it should work fine.
Also try to use specific header instead of bits/stdc++.h and use nullptr instead of NULL. You don't need the while loop inside the for loop as well. Get rid of it and just change the for loop like below -
for(int i = 1 ; i < siz ; i++)
{
temp2 = new node() ;
temp2->data = ara[i] ;
temp2->link = NULL ;
tmhead->link = temp2 ;
tmhead = tmhead->link ;
}
Notice that in case of user provided size 0, your code acts wrongly. Better to include header node creation, population inside the loop as well.
With all the mentioned changes the function may look like this -
node* create_linkedlist (int ara[] , int siz )
{
node* head = nullptr;
node* temp = nullptr;
node* last = nullptr; // Keeps track of last inserted node
for(int i = 0; i < siz; i++)
{
temp = new node();
temp->data = ara[i];
temp->link = nullptr;
if (!head) {
head = temp;
}
if (last) {
last->link = temp;
}
last = temp;
}
return head ;
}

Deleting duplicate elements in a list in c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a task to delete any duplicate elements from a list. I am using a struct and pointers for my functions. Here is the struct and the function:
struct node
{
int key;
node *next;
}*start = NULL;
int SIZE = 0;
Where size increments when an item is added. There is the function for deleting duplicates:
void del_dup()
{
if (!start) {
return;
}
if (SIZE == 1) {
return;
}
node * pointer = start->next;
node * prev = start;
node * mPointer = nullptr;
node * mPrev = nullptr;
for (int i = 0; i < SIZE - 1; i++)
{
if (pointer->next)
{
mPointer = pointer->next;
mPrev = pointer;
}
for (int j = i + 1; j <= SIZE; j++)
{
if (pointer->key == mPointer->key)
{
mPrev->next = mPointer->next;
delete mPointer;
}
else
{
mPrev = mPointer;
mPointer = mPointer->next;
}
}
prev = pointer;
pointer = pointer->next;
}
}
The thing is I get a crash at the if statement to compare if the two elements match:
if (pointer->key == mPointer->key)
The error is access violation type and nullptr for mPointer.
The list is filled from the user every time he runs the program with the values he wants. Here is the push function:
void push_start(int n) {
elem *p = start;
start = new elem;
start->key = n;
start->next = p;
SIZE++;
}
Any help to fix this would be appreciated. Thanks in forward!
For starters it is a bad idea to declare the variable SIZE outside the structure definition. In this case all functions that deal with the list will suffer from accessing to the global variable. You can not have more than one list in the program.
You could "wrap" the structure node in one more structure as for example
struct node
{
int key;
node *next;
};
struct list
{
node *head;
size_t /*int*/ size;
};
In this case each list would have its one data member size.
The function del_dup looks very confusing and you are using confusing names as for example pointer and mPointer. You should not rely on the variable SIZE that shall be decremented when a node is deleted.
I can suggest the following function implementation.
#include <iostream>
#include <cstdlib>
#include <ctime>
struct node
{
int key;
node *next;
} *head = nullptr;
size_t size;
void push_front( node * &head, int key )
{
head = new node { key, head };
++size;
}
std::ostream & display_list( node * head, std::ostream &os = std::cout )
{
os << size << ": ";
for ( const node *current = head; current; current = current->next )
{
os << current->key << ' ';
}
return os;
}
void del_dup( node * head )
{
for ( node *first = head; first; first = first->next )
{
for ( node *current = first; current->next; )
{
if ( current->next->key == first->key )
{
node *tmp = current->next;
current->next = current->next->next;
delete tmp;
--size;
}
else
{
current = current->next;
}
}
}
}
int main()
{
const size_t N = 10;
std::srand( ( unsigned int )std::time( nullptr ) );
for ( size_t i = 0; i < N; i++ )
{
push_front( head, std::rand() % ( int )N );
}
display_list( head ) << std::endl;
del_dup( head );
display_list( head ) << std::endl;
return 0;
}
The program output might look like
10: 2 2 3 3 8 5 6 2 6 1
6: 2 3 8 5 6 1
At a guess, you're at some point comparing keys with an already deleted node. For example, you're assigning mPointer = pointer->next, then possibly deleting mpointer, then at the end of the inner loop assigning pointer = pointer->next. So wouldn't it be possible for pointer->next to have already been deleted there?
Edit
Acutally it's much more likely that your inner loop condition is the problem. Try just:
for (int j = i + 1; j < SIZE; j++)
instead.

How to display all list values without endless loop

I have a list and I want to display it's values.
I want to see 1 2 3 4, but I have a endless loop like 1 2 3 4 1 2 3 4 1 2..
Can't understand, why?
struct node
{
int item;
node *next;
node(int x, node *t)
{
item = x;
next = t;
}
};
int main()
{
node *firstElement = new node(1, NULL);
firstElement->next = firstElement;
node *lastElement = firstElement;
for (int i = 2; i < 5; i++)
lastElement = (lastElement->next = new node(i, firstElement));
for (node *first = lastElement; first != 0; first = first->next)
cout << first->item << " ";
delete firstElement;
return 0;
}
Try using this code:
struct node
{
int item;
node *next;
node(int x, node *t)
{
item = x;
next = t;
}
};
int main()
{
node *firstElement = new node(1, NULL);
node *lastElement = firstElement;
for (int i = 2; i < 5; i++)
lastElement = (lastElement->next = new node(i, nullptr));
for (node *first = firstElement; first != 0; first = first->next)
cout << first->item << " ";
return 0;
}
IdeOne live code
The problem is that you set the "next" link of your last node to this node itself, not nullptr.
Also, it's better to delete the memory allocated
The problem is that your data structure has an infinite loop in itself: this line
firstElement->next = firstElement;
makes firstElement point back to itself, creating a circular list. When you add more elements, your list remains circular, so exit condition first == 0 is never achieved.
If you want your list to remain linear, not circular, your insertion code should be modified as follows:
node *firstElement = new node(1, NULL);
node *lastElement = firstElement;
for (int i = 2; i < 5; i++) {
lastElement->next = new node(i, lastElement->next)
lastElement = lastElement->next;
}
The printing code should start with firstElement:
for (node *current = firstElement; current != 0; current = current->next)
cout << current->item << " ";
Finally, deleting a single firstItem is not sufficient. You need a loop to traverse the whole list. Alternatively, you could chain deletion in the destructor by calling delete next, but this is dangerous, because recursive invocation of destructors may overflow the stack.
You have a loop in your list, because lastElement->next always points to firstElement. This is why first will never be equal to 0.
If you really need a loop I think you should write something like this:
node* p = firstElement;
do {
cout << p->item << " ";
p = p->next;
} while (p != firstElement);
The problem is that you create every node with firstElement as its next.
This would make sense if you were adding nodes to the front of the list, but you're adding them at the back, so the last node will point back to the start.
Since you're adding to the back, terminate the list on every insertion instead:
lastElement->next = new node(i, nullptr))

Linked List - pointers

I created a linked list and when I tried to print values of the nodes and used NULL as a bound, it didn't work. For example:
#include <iostream>
typedef struct Node;
typedef Node* Node_ptr;
struct Node
{
int i;
Node_ptr next;
};
int main()
{
Node_ptr ptr, head;
ptr = new Node;
head = ptr;
// load
for(int j = 0; j < 4; j++)
{
ptr->next = new Node;
ptr->i = j;
ptr = ptr->next;
}
// print
ptr = head;
while(ptr->next != NULL)
{
std::cout << "print: " << ptr->i << std::endl;
ptr = ptr->next;
}
}
However, when I run this code, the code gets stuck in an endless loop in the while loop.
It never understands that the linked list is only 5 nodes long, it just keeps on going. I can't understand why that happens.
You probably just need to initialize your pointers (to NULL), otherwise they'll just contain garbage, and will thus also appear as being valid pointers.
For instance:
for(j = 0; j < 4; j++)
{
ptr->next = new Node;
(ptr->next)->next = NULL;
ptr->i = j;
ptr = ptr->next;
}
Try value initializing your Node:
ptr = new Node();
instead of
ptr = new Node;
Otherwise, you'll just have garbage in the members.
while(ptr->next != NULL)
You clearly coded it to continue until ptr->next is NULL. Maybe you should set ptr->next to NULL for at least one item in the list? This is why it is common in C to memset(&object, 0, sizeof(object));, or in C++ to have a constructor.
typedef struct Node
{
int i;
Node* next;
Node() : i(0), next(NULL) {} //prevents this problem
}