The first element in the created list is always 0 - c++

I don't yet understand fully how linked lists and nodes in C/C++ work, but this is the function I use to add nodes to a list.
void AddNode(Node* head, int new_data)
{
Node* new_node = new Node();
Node *last = head;
new_node->data = new_data;
new_node->next = NULL;
if (head == NULL)
{
head = new_node;
return;
}
while (last->next != NULL)
{
last = last->next;
}
last->next = new_node;
}
The first element in the list will always be 0, what am I doing wrong?

In c++ , you must update
Node *last = head;
to
Node *& last = head;
In C, you must update
Node *last = head;
to
Node ** last = head;

I used the function AddNode as bellow:
Node* head = new Node();
AddNode(head, 1);
And i get the same problem like you.Because the first element will never change.There are two modify
(1) return the head
Node* AddNode(int new_data)
{
Node* head = NULL;
Node* new_node = new Node();
Node *last = head;
new_node->data = new_data;
cout << "-->" << new_node->data << endl;
new_node->next = NULL;
if (head == NULL)
{
head = new_node;
return head;
}
while (last->next != NULL)
{
last = last->next;
}
last->next = new_node;
return head;
}
use like this:
Node* head = AddNode(1);
(2)pass the head address,because you want to change it
void AddNode(Node** head, int new_data)
{
Node* new_node = new Node();
Node *last = *head;
new_node->data = new_data;
cout << "-->" << new_node->data << endl;
new_node->next = NULL;
if (*head == NULL)
{
*head = new_node;
return;
}
while (last->next != NULL)
{
last = last->next;
}
last->next = new_node;
}
use lie this:
Node* head = NULL;
AddNode(&head, 1);
Hope it's useful for you.

Related

Strange behaviour when I am trying to implement my linked list in c++

I'm trying to implement my singly linked list , and I have this problem:
When I'm trying to pushBack some elements in my linked list , it will print only the first one which I added.For example , if I try to pushBack 2,3,4 - it will print only 2.
In case if I want to pushUp some elements in my linked list , it will print only the third one which I added. For example , if I try to pushUp 2,3,4 - it will print only 4.
This is my code:
enter code here
#include<iostream>
#include<vector>
using namespace std;
struct Node {
int data;
Node* next;
};
class LinkedList {
private:
// Create pointers for head and tail
Node *head , *tail;
public:
LinkedList(){
// Initiate them as null pointers
head = NULL;
tail = NULL;
}
public:
void pushBack(int value){
// Should add a node at the end of the linked list
Node* temp = new Node(); // temporary node which should be added
temp->data = value; // value to store
temp->next = NULL; // pointer to the next node
if(head != NULL){
// If there are some elements , then
temp->next = tail->next;
tail = temp;
}
if(head == NULL){
// If there are no elements , our node will be a head and a tail in the same time.
head = temp;
tail = temp;
}
}
void pushUp(int value){
// Shound add a node at the beginning of the linked list
Node* temp = new Node();
temp->data = value;
temp->next = NULL;
if(head == NULL){
// If there are no elements , our node will be a head and a tail in the same time.
head = temp;
tail = temp;
}
if(head != NULL){
// If there are some elements , just make our node to be new head.
temp->next = head->next;
head = temp;
}
}
void traversal(){
Node *temp = new Node();
temp = head;
while(temp != NULL){
cout << temp->data << " ";
temp = temp->next;
}
}
};
int main(){
// Pointer for our first node.
LinkedList a;
a.pushUp(2);
a.pushUp(124);
a.pushUp(3);
// a.pushBack(2);
// a.pushBack(124);
// a.pushBack(3); // Outputs only 2
a.traversal(); // Outputs only 3
}
You are missing edge cases. When you add the first node you are pointing it via head and tail ok but then you should check if there is only one node by comparing the address. And you should consider it for both function because if there is only one node head tail will change or head will be overwritten in your code.

class LinkedList {
private:
// Create pointers for head and tail
Node *head , *tail;
public:
LinkedList(){
// Initiate them as null pointers
head = NULL;
tail = NULL;
}
public:
void pushBack(int value){
// Should add a node at the end of the linked list
Node* temp = new Node(); // temporary node which should be added
temp->data = value; // value to store
temp->next = NULL; // pointer to the next node
if(head != NULL){
// If there are some elements , then
if(tail!=NULL){
tail->next = temp;
}else {
tail = temp;
head->next = tail;
}
}else {
// If there are no elements , our node will be a head and a tail in the same time.
head = temp;
}
}
void pushUp(int value){
// Shound add a node at the beginning of the linked list
Node* temp = new Node();
temp->data = value;
temp->next = NULL;
if(head == NULL){
// If there are no elements , our node will be a head and a tail in the same time.
head = temp;
}else {
// If there are some elements , just make our node to be new head.
if(tail != NULL){
temp->next = head;
head = temp;
}else {
tail = head;
head = temp;
temp->next = tail;
}
}
}
void traversal(){
Node *temp = new Node();
temp = head;
while(temp != NULL){
cout << temp->data << " ";
temp = temp->next;
}
}
};

```

insert at end of linked list

I am 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:
node* Insert(node* head, int data)
{
if (head == NULL) {
head = new node();
head->data = data;
head->link = NULL;
return head;
}
else {
node* temp = head;
while (temp != NULL) {
temp = temp->link;
}
node* temp2 = new node();
temp2->data = data;
temp2->link = NULL;
(temp->link) = temp2;
return head;
}
}
Change the condition in while construct from:
while (temp!=NULL) {
temp=temp->link;
}
To
while (temp->link!=NULL) {
temp=temp->link;
}
In statement, temp->link = temp2, temp is a null pointer. You were dereferencing a NULL pointer.
To append a node at the back, temp pointer should point to the last node of the linked list. So, in the while loop, you need to just stop linked list traversal when you have reached the last node, i.e, the node whose link member points to nothing (has NULL). while (temp->link!=NULL) will stop at the last node as last node will have link member pointing to NULL.
You can simplify your logic by doing this:
void Insert(node **pnode, int data)
{
while (*pnode) {
pnode = &(*pnode)->link;
}
*pnode = new node(data, NULL);
}
assuming you have a node constructor that initializes data and link from arguments.
Instead of calling it as
head = Insert(head, 42);
you'd now do
Insert(&head, 42);
change while(temp!=NULL) to while(temp->link!=NULL)
node* Insert(node* head, int data)
{
if (head == NULL) {
head = new node();
}
else {
while (head->link != NULL) {
head = head->link;
}
head = head->link = new node();
}
head->data = data;
head->link = NULL;
return head;
}

Linked List insertion issue

I was trying out Linked List and I have a bit of problem with my insertNode1 function. This function is supposed to insert a new node after the inputted node by the user. The result doesn't show what I wanted to show. I wanted the number 5 to be after 3, but it doesn't show how I wanted it.
#include <iostream>
using namespace std;
class List {
struct node {
float data;
node* next;
};
node* head;
public:
void appendNode(float);
void insertNode(float);
void insertNode1(float,float);
void deleteNode(float);
void displayList();
List(){
head = NULL;
}
~List(){
node *nodePtr, *nextNode;
nodePtr = head;
while (nodePtr != NULL){
nextNode = nodePtr->next;
delete nodePtr;
nodePtr = nextNode;
}
}
};
void List::appendNode(float d)
{
node *newNode, *nodePtr;
newNode = new node;
newNode->data = d;
newNode->next = NULL;
if (!head){
head = newNode;
}
else {
nodePtr = head;
while (nodePtr->next){
nodePtr = nodePtr->next;
}
nodePtr->next = newNode;
}
}
void List::insertNode(float d){
node *newNode, *nodePtr, *prevNode=NULL;
newNode = new node;
newNode->data = d;
if (head== NULL)
{
head = newNode;
newNode->next = NULL;
}
else {
nodePtr = head;
while (nodePtr != NULL && nodePtr->data < d){
prevNode = nodePtr;
nodePtr = nodePtr->next;
}
if (prevNode == NULL){
head = newNode;
newNode->next = nodePtr;
}
else {
prevNode->next = newNode;
newNode->next = nodePtr;
}
}
}
void List::insertNode1(float p, float d){
node *newNode, *nodePtr, *selectedNode=NULL;
newNode = new node;
newNode->data = d;
nodePtr = head;
selectedNode = nodePtr;
selectedNode->data = p;
if (head != NULL){
head = newNode;
newNode->next = NULL;
}
else {
while (nodePtr->next != NULL && nodePtr->data != p){
nodePtr = nodePtr->next;
}
if (selectedNode == NULL){
head = newNode;
selectedNode->next = NULL;
}
else {
selectedNode->next = newNode;
}
}
}
void List::deleteNode(float da){
node *nodePtr, *previousNode=NULL;
if (head == NULL){
return;
}
if (head ->data == da){
nodePtr = head->next;
delete head;
head = nodePtr;
}
else{
nodePtr = head;
while (nodePtr != NULL && nodePtr->data != da){
previousNode = nodePtr;
nodePtr = nodePtr->next;
}
previousNode->next = nodePtr->next;
delete nodePtr;
}
}
void List::displayList(){
node *nodePtr;
nodePtr = head;
while (nodePtr!= NULL){
cout << nodePtr->data << endl;
nodePtr = nodePtr->next;
}
}
int main(){
List lobj;
lobj.appendNode(3);
lobj.appendNode(6.4);
lobj.appendNode(4.5);
lobj.appendNode(7.8);
lobj.insertNode(1.5);
lobj.displayList();
cout << "after deleting and adding a new node" << endl;
lobj.deleteNode(6.4);
lobj.displayList();
lobj.insertNode1(3, 5);
lobj.displayList();
system("pause");
}
At the beginning of your void List::insertNode1(float p, float d) function:
nodePtr = head;
selectedNode = nodePtr;
selectedNode->data = p;
Here, selectedNode points at the head of the list and you seem to overwrite the data of that node with the value of p, which I cannot help but feel is not what you meant to do.
There are a few issues inside List::insertNode1.
nodePtr = head;
selectedNode = nodePtr;
selectedNode->data = p;
Here selectedNode points at head but then you set the first data value to p.
if (head != NULL){
head = newNode;
newNode->next = NULL;
}
This part only executes when head is not null. This means you get rid of the entire list every time this is run. This is why the last call to list::displayList only prints 5.
if (selectedNode == NULL){
head = newNode;
selectedNode->next = NULL;
}
Here selectedNode is NULL. first you set head to be a new node but this doesn't change selectedNode. If you ran this method on an empty list your program would segfault here. You should be setting the next of head or newNode to NULL here, not selectedNode.
else {
selectedNode->next = newNode;
}
Here selectedNode still points to head. You change nodePtr but this doesn't also change selectedNode.

C++ Linked list print error

I don't understand why the display() func show me only the first member of the list. I think I did a mess with pointers, but I can't understand where. I have compared this to other linked list source and it seem that the function is written in the-good-way.
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
struct Node
{
int Data;
Node * next;
};
void initNode(struct Node *head,int n);
void AddNode(int n,Node* head);
void display(Node* head);
int main()
{
Node * head = new Node;
initNode(head,5);
display(head);
AddNode(10,head);
display(head);
AddNode(15,head);
display(head);
cin.get();
return 0;
}
void AddNode(int n,Node * head)
{
Node * node = new Node;
node->Data = n;
node->next = NULL;
Node * nextNode = head;
while(nextNode)
{
if(nextNode->next == NULL)
{
nextNode->next = node;
}
nextNode = nextNode->next;
}
}
void display(Node * head)
{
while(head)
{
cout << head->Data << " "<<endl;
head = head->next;
}
}
void initNode(struct Node *head,int n)
{
head->Data = n;
head->next = NULL;
}
Your AddNode method is over-complicated. Do something like this to add to the front:
Node *AddNode(int n, Node *head)
{
Node *newNode = new Node;
newNode->Data = n;
newNode->next = head;
return newNode;
}
Or to add to the end:
Node *AddNode(int n, Node *head)
{
Node *newNode = new Node;
newNode->Data = n;
newNode->next = NULL;
if(head == NULL) return newNode;
Node *current = head;
while(current->Next != NULL)
{
current = current->Next;
}
current->Next = newNode;
return head;
}
Doing AddNode this way you will not need initNode. Now you can just day:
Node *head = NULL;
head = AddNode(5, head);
head = AddNode(10, head);
head = AddNode(15, head);
display(head);
Also, you don't need to say struct Node in C++, it is only required in C.
Function AddNode has an infinite loop.
void AddNode(int n,Node * head)
{
Node * node = new Node;
node->Data = n;
node->next = NULL;
Node * nextNode = head;
while(nextNode)
{
if(nextNode->next == NULL)
{
nextNode->next = node;
}
nextNode = nextNode->next;
}
}
Let assume that you have only one element that is the head (after a call of initNode). And as the result head->next = NULL. So inside the body of the loop you make assignment
nextNode->next = node;
Now head->next is not equal to NULL. So after statement
nextNode = nextNode->next;
nextNode caontains the new element. As it is not equal to NULL then iteration of the loop will be repeated. Again for the new node its data member next is equal to NULL. And you add it to it itself.
Now you have no any element in the list that would have data member next equal to NULL. So you are unable to add new elements. The last element contains reference to itself.
You could write the function the following way
void AddNode(int n,Node * head)
{
Node * node = new Node;
node->Data = n;
node->next = NULL;
Node * nextNode = head;
while( nextNode -> next ) nextNode = nextNode->next;
nextNode->next = node;
}
But take into account that it is assumed that head is not equal to NULL. otherwise the function will be incorrect. I think that you should redesign you list.
In your AddNode function add a break in the if block.
void AddNode(int n,Node * head)
{
Node * node = new Node;
node->Data = n;
node->next = NULL;
Node * nextNode = head;
while(nextNode)
{
if(nextNode->next == NULL)
{
nextNode->next = node;
break;
}
nextNode = nextNode->next;
}
}
Now it should add properly.
Node * nextNode = head;
while(nextNode)
{
if(nextNode->next == NULL)
{
nextNode->next = node;
}
nextNode = nextNode->next;
}
The problem is this block of code. When you find the end of the list (if nextNode->next == NULL) you need to break out of the loop. Try it with an example to convince yourself.
Each time you add a node you traverse from head to the end of the list
You can change it as follows
void AddNode(int n){
Node *node=new Node;
node->data=n;
node->next=NULL; //head is global
if(head==NULL){
t=head=n;
}
else{
t->next=n; //t is global
t=t->next;
}
}

Insert Node in a Sorted Doubly linked list

I am not able to figure out, why is my code to insert into a sorted doubly linked list failing on some test cases.Please let me know. I dont know of the test cases, they are system generated.
Node* SortedInsert(Node *head,int data)
{
// Complete this function
// Do not write the main method.
Node * temp = (Node*)malloc(sizeof(Node));
temp->data = data;
temp->next = NULL;
temp->prev = NULL;
if (head == NULL)
{
head = temp;
return head;
}
if (temp->data <= head->data)
{
temp->next = head;
head->prev = temp;
head = temp;
return head;
}
Node *curr = head;
while (curr->next!=NULL)
{
if (temp->data <= curr->data)
{
curr->prev->next = temp;
temp->prev = curr->prev;
temp->next = curr;
curr->prev = temp;
return head;
}
curr = curr->next;
}
curr->next = temp;
temp->prev = curr;
return head;
}
Thanks
Once you reach the last node, you should again compare its data with the new node and insert accordingly.
curr->next = temp;
temp->prev = curr;
return head;
}
If execution reaches this part, then at present curr is pointing to the last node. Now you should again compare its data like the following:
if (temp->data <= curr->data)
{ // insert before last node
curr->prev->next = temp;
temp->prev = curr->prev;
temp->next = curr;
curr->prev = temp;
return head;
}
// else insert at the end.
curr->next = temp;
temp->prev = curr;
return head;
}
Alternatively, you can write an if condition for node at the end of the list
Node* SortedInsert(Node *head,int data)
{
struct Node* p = head;
struct Node* q = NULL;
struct Node* r = new Node;
r->data=data;
r->prev=NULL;
r->next=NULL;
if(p==NULL){
p=r;
head=p;
}
else if(p!=NULL&&p->data>r->data){
p->prev=r;
r->next=p;
p->next=NULL;
head = r;
}
else{
p=head;
while(p!=NULL) {
if(p!=NULL&&p->data>r->data){ //If node is not at the end of list and smaller than some node
(p->prev)->next = r;
r->next = p;
r->prev = p->prev;
p->prev=r;
return head;
}
else if(p->next==NULL) //If node is at the end of list
{
p->next = r;
r->prev = p;
r->next = NULL;
return head;
}
else{}
p=p->next;
}
}
return head;
}
/*
* For reference:
*
* link to the problem :-
* https://www.hackerrank.com/challenges/insert-a-node-into-a-sorted-doubly-linked-list
*
* DoublyLinkedListNode {
* int data;
* DoublyLinkedListNode* next;
* DoublyLinkedListNode* prev;
* };
*
* Function to insert a node in sorted DLL with given data & return head
*/
DoublyLinkedListNode* sortedInsert(DoublyLinkedListNode* head, int data) {
DoublyLinkedListNode** prev = &head;
DoublyLinkedListNode* newNode = new DoublyLinkedListNode(data);
while ( *prev && ((*prev)->data <= data) ) {
prev = &(*prev)->next;
}
newNode->prev = *prev;
newNode->next = *prev;
*prev = newNode;
return head;
}
This solution works in all cases (insert in between, insert at the head, insert at the end etc). I was just trying to write a code without any conditions. While searching for some error, I ended up on this SO thread. Do correct me if this solution doesn't work for some test cases.
This is my code that passed all the test cases.
DoublyLinkedListNode* sortedInsert(DoublyLinkedListNode* head, int data) {
DoublyLinkedListNode *temp = head;
if (!temp) {
temp = new DoublyLinkedListNode(data);
head = temp;
return head;
}
while (temp->data < data && temp->next != nullptr) {
temp = temp->next;
}
if (temp->data > data) {
DoublyLinkedListNode *t = new DoublyLinkedListNode(data);
t->next = temp;
if (temp == head) {
head = t;
temp->prev = t;
return head;
}
temp->prev->next = t;
t->next = temp;
temp->prev = t;
} else {
DoublyLinkedListNode *t = new DoublyLinkedListNode(data);
t->next = temp->next;
temp->next = t;
temp->next->prev = temp;
if (t->next != nullptr) t->next->prev = t;
}
return head;
}
Here is some code in order to Insert a Node in Sorted Doubly Linked List
Node* SortedInsert(Node *head,int data)
{
struct Node *temp;
struct Node *newNode = new Node();
newNode->data=data;
newNode->next=NULL;
newNode->prev=NULL;
temp=head;
if(head==NULL)
{
head = newNode;
}
else
{
while(temp!=NULL)
{
if(temp->data<data&&temp->next!=NULL)
{
temp=temp->next;
}
else
{
if(temp->next==NULL&&temp->data<data)
{
temp->next = newNode;
newNode->prev = temp;
break;
}
else if(temp->prev==NULL&&temp->data>data)
{
newNode->next=temp;
temp->prev = newNode;
head=newNode;
break;
}
else
{
newNode->next = temp;
newNode->prev = temp->prev;
temp->prev->next =newNode;
temp->prev=newNode;
break;
}
}
}
}
return head;
}
Here is the complete C++ program for inserting a node at appropriate position in a sorted doubly linked list:
void InsertInSortedDoublyLinkedList()
{
Node *head;
head = CreateDoublyLinkList(3);
PrintDoublyLinkedList(head);
head = SortedInsert(head, 6);
printf("\n Linked list after insertion in sorted order\n");
PrintDoublyLinkedList(head);
}
void PrintDoublyLinkedList(Node *head)
{
Node *temp = head;
printf("NULL -> ");
while (temp)
{
printf("%d ->", temp->data);
temp = temp->next;
}
printf("NULL");
}
Node* CreateDoublyLinkList(int numberOfNodes)
{
Node *head = NULL, *temp, *temp1;
int startingValue = 3;
if (numberOfNodes == 0)
{
return head;
}
temp = (Node*)malloc(sizeof(Node));
temp->data = startingValue;
temp->next = NULL;
temp->prev = NULL;
head = temp;
startingValue += 2;
numberOfNodes--;
for (; numberOfNodes > 0; numberOfNodes--, startingValue += 2, temp = temp->next)
{
temp1 = (Node*)malloc(sizeof(Node));
temp1->data = startingValue;
temp1->next = NULL;
temp1->prev = temp;
temp->next = temp1;
}
return head;
}
Node* SortedInsert(Node *head,int data)
{
Node *temp = NULL, *temp1,*newNode;
int nodeInserted = 0;
if (head == NULL)
{
head = (Node*) malloc(sizeof(Node));
head->data = data;
head->next = NULL;
head->prev = NULL;
}
else
{
if (head->data > data)
{
//insertion need to take place before head itself.
newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = head;
newNode->prev = NULL;
head->prev = newNode;
head = newNode;
}
else
{
temp1 = head;
temp = head ->next;
while (temp)
{
if (temp->data > data)
{
//we need to insert the node before temp
newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->prev = temp1;
newNode->next = temp;
temp1->next = newNode;
temp->prev = newNode;
nodeInserted = 1;
break;
}
temp1 = temp;
temp = temp->next;
}
if (!nodeInserted)
{
//node insertion need to take place at tail.
newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->prev = temp1;
newNode->next = NULL;
temp1->next = newNode;
}
}
}
return head;
}
struct Node
{
int data;
Node *next;
Node *prev;
}
Node* SortedInsert(Node *head,int data)
{
Node* p1,*p2;
int n=10;
p2=(Node*)malloc(sizeof(struct Node));
p2->next=NULL;
p2->prev=NULL;
p2->data=data;
p1=head;
if(p1==NULL)
return p2;
while(p1->next!=NULL)
{
if(p1->data<data)
p1=p1->next;
else
break;
}
/*Three cases arise when p1->next == NUll i.e. we are end of list
case 1: insert after the end
case 2: insert in between last and second last node
case 3: insert node at the beginning of the list
*/
if(p1->next==NULL)
{
if(p1->data<data)
{
p2->prev=p1;
p1->next=p2;
}
else if(p1->data > data && p1->prev!=NULL)
{
p2->next=p1;
p2->prev=p1->prev;
if(p1->prev!=NULL)
p1->prev->next=p2;
p1->prev=p2;
}
else
{
p2->next=p1;
p2->prev=p1->prev;
if(p1->prev!=NULL)
p1->prev->next=p2;
p1->prev=p2;
head=p2;
}
}
// Here we have only one case where new node is inserted between two nodes of the list
else
{
p2->next=p1;
p2->prev=p1->prev;
if(p1->prev!=NULL)
p1->prev->next=p2;
p1->prev=p2;
}
return head;
}