I am trying to create a doubly linked list and then printing its value but the output is showing only first value and then the whole program is crashing.
I can't understand where is the problem in the code .
Input
3
1 2 3
Expected output
1 2 3
current output
1
#include<iostream>
#include<stdlib.h>
using namespace std;
class node //declation of node
{
public:
int data;
node *next;
node *prev;
};
node *makenode(node *head,int val) //function to create node
{
node *newnode=new node;
node *temp;
newnode->data=val;
newnode->next=0;
newnode->prev=0;
if(head==0) temp=head=newnode;
else
{
temp->next=newnode;
newnode->prev=temp;
temp=newnode;
}
return head;
}
void display(node *head) //display function
{
system("cls"); //clearing output screen
while(head!=0)
{
cout<<head->data<<" ";
head=head->next;
}
}
int main()
{
node *head;
head=0;
int val;
int s; //size of list
cout<<"ENTER THE SIZE OF LIST";
cin>>s;
system("cls");
for(int i=0;i<s;i++)
{
cout<<"ENTER THE "<<i+1<<" VALUE\n";
cin>>val;
head=makenode(head,val); //calling makenode and putting value
}
display(head); //printing value
return 0;
}
node *makenode(node *head,int val) //function to create node
{
node *newnode=new node;
node *temp; // #1
newnode->data=val;
newnode->next=0;
newnode->prev=0;
if(head==0) temp=head=newnode;
else
{
temp->next=newnode; // #2
Between the lines marked #1 and #2 above, what exactly is setting the variable temp to point to an actual node rather than pointing to some arbitrary memory address?
"Nothing", I hear you say? Well, that would be a problem :-)
In more detail, the line:
node *temp;
will set temp to point to some "random" location and, unless your list is currently empty, nothing will change that before you attempt to execute:
temp->next = newnode;
In other words, it will use a very-likely invalid pointer value and crash if you're lucky. If you're unlucky, it won't crash but will instead exhibit some strange behaviour at some point after that.
If you're not worried about the order in the list, this could be fixed by just always inserting at the head, with something like:
node *makenode(node *head, int val) {
node *newnode = new node;
newnode->data = val;
if (head == 0) { // probably should use nullptr rather than 0.
newnode->next = 0;
newnode->prev = 0;
} else {
newnode->next = head->next;
newnode->prev = 0;
}
head = newnode;
return head;
}
If you are concerned about order, you have to find out where the new node should go, based on the value, such as with:
node *makenode(node *head, int val) {
node *newnode = new node;
newnode->data = val;
// Special case for empty list, just make new list.
if (head == 0) { // probably should use nullptr rather than 0.
newnode->next = 0;
newnode->prev = 0;
head = newnode;
return head;
}
// Special case for insertion before head.
if (head->data > val) {
newnode->next = head->next;
newnode->prev = 0;
head = newnode;
return head;
}
// Otherwise find node you can insert after, and act on it.
// Checknode will end up as first node where next is greater than
// or equal to insertion value, or the last node if it's greater
// than all current items.
node *checknode = head;
while (checknode->next != 0 && (checknode->next->data < val) {
checknode = checknode->next;
}
// Then it's just a matter of adjusting three or four pointers
// to insert (three if inserting after current last element).
newnode->next = checknode->next;
newnode->prev = checknode;
if (checknode->next != 0) {
checknode->next->prev = newnode;
}
checknode->next = newnode;
return head;
}
You aren't actually linking anything together. This line: if(head==0) temp=head=newnode; is the only reason your linked list contains a value at all. The very first value sets head equal to it and when you print head you get that value. In order to properly do a linked list you need a head and tail pointer. The head points to the first element in the list and the tail points to the last. When you add an element to the end of the list you use tail to find the last element and link to it. It is easiest to make Linked List a class where you can encapsulate head and tail:
struct Node {
public:
int data;
node *next;
node *prev;
Node(int data) : data(data), next(nullptr), prev(nullptr) {} // constructor
};
class LinkedList {
private:
Node* head;
Node* tail;
public:
LinkedList() { head = tail = nullptr; }
// This function adds a node to the end of the linked list
void add(int data) {
Node* newNode = new Node(data);
if (head == nullptr) { // the list is empty
head = newNode;
tail = newNode;
}
else { // the list is not empty
tail->next = newNode; // point the last element to the new node
newNode->prev = tail; // point the new element to the prev
tail = tail->next; // point the tail to the new node
}
}
};
int main() {
LinkedList lList;
lList.add(1);
lList.add(2);
// etc...
return 0;
}
I have written this code for implementing Linked List in c++. It worked perfectly till i added the insert at end function to it. Please see what's wrong! Without the insertatend function, output is correct. After adding that function, the output is 1 10 which is actually the insert at start and end's outputs.
void List::insertatend(int num)
{
Node *new_node=new Node(num);
if(listptr==NULL)
listptr=new_node;
else
for(Node *temp=listptr; temp->next!=NULL; temp=temp->next)
temp->next=new_node;
}
The problem is in the lines:
for(Node *temp=listptr; temp->next!=NULL; temp=temp->next)
temp->next=new_node;
It seems like you haven't walked through the logic of how the code works.
You will first need to iterate until temp->next is NULL and then use
temp->next=new_node;
The code to implement that logic is:
Node* temp = listptr;
for ( ; temp->next != NULL; temp = temp->next )
{
// Do nothing in the loop.
}
temp->next = new_node;
Here's the updated function:
void List::insertatend(int num)
{
Node* new_node = new Node(num);
if( listptr == NULL)
{
listptr = new_node;
}
else
{
Node* temp = listptr;
for ( ; temp->next != NULL; temp = temp->next )
{
}
temp->next = new_node;
}
}
Go through the basic logic of how to add the every new node at end of previous node.Bug is in below two lines of insertatend function, explanation I mentioned in comments.
for(Node *temp=listptr; temp->next!=NULL; temp=temp->next) //it should be dummy loop
temp->next=new_node;//In all old nodes next part will replace by new_node which is wrong
Modiy Insert_end() function as
void List::insertatend(int num)
{
Node *new_node=new Node(num);
if(listptr==NULL)
listptr=new_node;
else{
Node *temp=listptr;
for( temp ; temp->next!=NULL ; temp=temp->next); /** rotate dummy loop until temp is not reaching to last node **/
temp->next = new_node;// in last node next put the new node address
new_node->next = 0; // and new node nnext put the zero
}
}
I am implementing a link list with cpp,what is wrong with the following code?
Every time i step into the function---AddToTail, the "list" can't get correct value. It changes it value to the new constructed node.
#include <iostream>
using namespace std;
struct Node
{
int value;
Node * next;
};
void AddToTail(Node* &list, int value)
{
Node newnode;
newnode.value = value;
newnode.next = NULL;
if (list == NULL)
list = &newnode;
else
{
Node * list1 = list;
while (list1->next != NULL)
{
list1 = list1->next;
}
list1->next = &newnode;
int a = 1;
}
}
int main()
{
Node *list=NULL;
AddToTail(list, 1);
AddToTail(list, 2);
AddToTail(list, 3);
while (list->next != NULL)
{
cout << list->value << endl;
list = list->next;
}
system("pause");
}
void AddToTail(Node* &list, int value)
{
Node newnode;
// Set up fields of newnode.
// Store address of newnode into some other data structure.
}
This is your issue. You are creating a node on the stack and this node will go out of scope at the end of the function. The reason it seems to be interfering with later node creations is because re-entering the function will almost certainly create newnode at exactly the same address as in the previous call.
If you want objects to survive function scope, you're going to need to allocate them dynamically, something like:
void AddToTail (Node *&list, int value) {
Node *newnode = new Node(); // create on heap.
newnode->value = value; // set up node.
newnode->next = nullptr;
if (list == nullptr) { // list empty,
list = newnode; // just create.
return;
}
Node *lastNode = list; // find last item.
while (lastNode->next != nullptr)
lastNode = lastNode->next;
lastNode->next = newnode; // append to that.
}
I was writing a simple function to insert at the end of a linked list on C++, but finally it only shows the first data. I can't figure what's wrong. This is the function:
void InsertAtEnd (node* &firstNode, string name){
node* temp=firstNode;
while(temp!=NULL) temp=temp->next;
temp = new node;
temp->data=name;
temp->next=NULL;
if(firstNode==NULL) firstNode=temp;
}
What you wrote is:
if firstNode is null, it's replaced with the single node temp which
has no next node (and nobody's next is temp)
Else, if firstNode is not null, nothing happens, except that the temp
node is allocated and leaked.
Below is a more correct code:
void insertAtEnd(node* &first, string name) {
// create node
node* temp = new node;
temp->data = name;
temp->next = NULL;
if(!first) { // empty list becomes the new node
first = temp;
return;
} else { // find last and link the new node
node* last = first;
while(last->next) last=last->next;
last->next = temp;
}
}
Also, I would suggest adding a constructor to node:
struct node {
std::string data;
node* next;
node(const std::string & val, node* n = 0) : data(val), next(n) {}
node(node* n = 0) : next(n) {}
};
Which enables you to create the temp node like this:
node* temp = new node(name);
You've made two fundamental mistakes:
As you scroll through the list, you roll off the last element and start constructing in the void behind it. Finding the first NULL past the last element is useless. You must find the last element itself (one that has its 'next' equal NULL). Iterate over temp->next, not temp.
If you want to append the element at the end, you must overwrite the last pointer's NULL with its address. Instead, you write the new element at the beginning of the list.
void InsertAtEnd (node* &firstNode, string name)
{
node* newnode = new node;
newnode->data=name;
newnode->next=NULL;
if(firstNode == NULL)
{
firstNode=newnode;
}
else
{
node* last=firstNode;
while(last->next != NULL) last=last->next;
last->next = newnode;
}
}
Note, this gets a bit neater if you make sure never to feed NULL but have all lists always initialized with at least one element. Also, inserting at the beginning of list is much easier than appending at the end: newnode->next=firstNode; firstNode=newnode.
The last element in your list never has it's next pointer set to the new element in the list.
The problem is that you are replacing the head of the linked list with the new element, and in the process losing the reference to the actual list.
To insert at the end, you want to change the while condition to:
while(temp->next != null)
After the loop, temp will point to the last element in the list. Then create a new node:
node* newNode = new node;
newNode->data = name;
newNode->next = NULL;
Then change temps next to this new node:
temp->next = newNode;
You also do not need to pass firstNode as a reference, unless you want NULL to be treated as a linked list with length 0. In that case, you will need to significantly modify your method so it can handle the case where firstNode is NULL separately, as in that case you cannot evaluate firstNode->next without a segmentation fault.
If you don't want to use reference pointer, you could use pointer to pointer. My complete code goes like below:
void insertAtEnd(struct node **p,int new_data)
{
struct node *new_node=(struct node *)malloc(sizeof(struct node));
new_node->data=new_data;
new_node->next=NULL;
if((*p)==NULL)//if list is empty
{
*p=new_node;
return;
}
struct node* last=*p;//initailly points to the 1st node
while((last)->next != NULL)//traverse till the last node
last=last->next;
last->next=new_node;
}
void printlist(struct node *node)
{
while(node != NULL);
{
printf("%d->",node->data);
node=node->next;
}
}
int main()
{
struct node *root=NULL;
insertAtEnd(&root,1);
insertAtEnd(&root,2);
insertAtEnd(&root,3);
insertAtEnd(&root,4);
insertAtEnd(&root,5);
printlist(root);
return 0;
}
Understanding the need of the below two variables is key to understanding the problem:
struct node **p: Because we need to link it from the root node created in the main.
struct node* last: Because if not used, the original content will be changed with the contents of the next node inside the while loop. In the end only 2 elements will be printed, the last 2 nodes, which is not desired.
void addlast ( int a)
{
node* temp = new node;
temp->data = a;
temp->next = NULL;
temp->prev=NULL;
if(count == maxnum)
{
top = temp;
count++;
}
else
{
node* last = top;
while(last->next)
last=last->next;
last->next = temp;
}
}
#include <bits/stdc++.h>
using namespace std;
class Node
{
public:
int data;
Node *next;
};
void append(Node *first, int n)
{
Node *foo = new Node();
foo->data = n;
foo->next = NULL;
if (first == NULL)
{
first = foo;
}
else
{
Node *last = first;
while (last->next)
last = last->next;
last->next = foo;
}
}
void printList(Node *first)
{
while (first->next != NULL)
{
first = first->next;
cout << first->data << ' ';
}
}
int main()
{
Node *node = new Node();
append(node, 4);
append(node, 10);
append(node, 7);
printList(node);
return 0;
}
Output: 4 10 7
You can use this code:
void insertAtEnd(Node* firstNode, string name)
{
Node* newn = new Node; //create new node
while( firstNode->next != NULL ) //find the last element in yur list
firstNode = firstNode->next; //he is the one that points to NULL
firstNode->next = newn; //make it to point to the new element
newn->next = NULL; //make your new element to be the last (NULL)
newn->data = name; //assign data.
}
void InsertAtEnd (node* &firstNode, string name){
node* temp=firstNode;
while(temp && temp->next!=NULL) temp=temp->next;
node * temp1 = new node;
temp1->data=name;
temp1->next=NULL;
if(temp==NULL)
firstNode=temp1;
else
temp->next= temp1;
}
while loop will return at temp==null in your code instead you need to return last node pointer from while loop like this
while(temp && temp->next!=NULL) temp=temp->next;
and assign a new node to next pointer of the returned temp node will add the data to the tail of linked list.
I donĀ“t get this, when I call head->valueit returns me the last value added to the linked list. Should it not return me the first item since head is only set when it is empty? correct? I am thinking maybe there is there some other bug in the code.
void LinkedListPQueue::enqueue(const string& elem) {
cell *newCell = new cell;
newCell->value = elem;
newCell->next = NULL;
if(this->isEmpty()) {
this->head = this->tail = newCell;
} else {
// find smallest and put it there
this->tail->next = newCell;
this->tail = newCell;
}
}
declared in header
struct cell {
std::string value;
cell *next;
};
cell *head, *tail;
My be isEmpty is not implemented correctly so everytime you add a new node you re-assign the head to that node