C++ linked list nodes - c++

I have very basic concepts of linked list with C++. Here I have nodes linked, but the idea is to delete the last node, how do I achieve this?
This is the portion of code aimed to delete the last node:
//deleting node here
age* temp = head;
temp->next->next;//!=NULL
temp = temp->next;
//temp->next = NULL;
delete temp;
#include<iostream>
using namespace std;
struct age{
int a;
age *next;
};
age *head,*current,*node1,*node2,*ona;
int main(){
//creating a first node
age *node1=new age();
head=node1;
node1->a=10;
//creating a second node
age *node2=new age();
node2->a=20;
//link nodes
node1->next=node2;
node2->next=NULL;
//insertion of node ona between node 1 and node 2
ona=new age;
ona->a=15;
ona->next=node1->next;
node1->next=ona;
//deleting node here
age* temp = head;
temp->next->next;//!=NULL
temp = temp->next;
//temp->next = NULL;
delete temp;
//displaying the otput
current=head;
while(current!=NULL){
cout<<current->a<<endl;
current=current->next;
}
}

I suggest to have a look here:
For plain C development: https://www.learn-c.org/en/Linked_lists
On this site all standard methods for handling linked lists are explained and you can find code snippets for every operation.
For CPP development: https://www.codesdope.com/blog/article/c-deletion-of-a-given-node-from-a-linked-list-in-c/
On this site you can find an example coded in CPP OOP style.
I change the C example a little bit to fit your code example:
void remove_last(age * head) {
/* if there is only one item in the list, remove it */
if (head->next == NULL) {
delete head;
head = NULL;
return;
}
/* get to the second to last node in the list */
node_t * current = head;
while (current->next->next != NULL) {
current = current->next;
}
/* now current points to the second to last item of the list, so let's remove current->next */
delete(current->next);
current->next = NULL;
}

Related

LInked list not reversing

Bellow, I have some code that is supposed to display a linked list, reverse it, and then display the now reversed linked list, but it seems that it never displays. My only guess is that somehow the linked list is becoming null. What am I doing wrong? Both the reverse function and the function that should display the reversed array run, but there is no visual output after.
#include <iostream>
using namespace std;
class Node{
public:// creation of a simple Node class
int data;
Node* next;
};
class LinkedList{
public:
Node* head;
LinkedList() { head = NULL; }
void append( int x){
Node* temp = new Node;// allocate new node
Node* end = head;//used later
temp->data = x;//giving the node data
temp->next = NULL;//since this node will be last make the next of it NULL
if(head == NULL){// if list is empty then set new Node as the head
head = temp;
return;
}
while(end->next != NULL){// go until the last node
end = end->next;
}
end->next = temp;// change the next of the last node to the new node.
}
void reverse(){
Node* current = head;
Node* next = NULL;
Node* prev = NULL;
while(current != NULL){
next = current->next;// Store next
current->next = prev;// Reverse current node's pointer
prev = current;// Move pointers one position ahead.
current = next;
}
head = prev;
}
void display(){
while(head != NULL){// print data while not out of bounds
cout<<" "<<head->data;
head = head->next;
}
}
};
int main() {
LinkedList list;
list.append(1);
list.append(10);
list.append(32);
list.append(64);
list.append(102);
list.append(93);
list.display();
cout<<endl;
list.reverse();
cout<<"list reversed"<<endl;
list.display();
cout<<"reverse display ran"<<endl;
Turns out it was an oversight on my part, I should have set up a temporary variable that represented the head, in my current program I'm changing what head references in order to loop through the linked list, and thus setting head equal to null once it reaches the end of the list a correct way to write the display function would be:
void display(){
Node* temp = head;
while(temp != NULL){// print data while not out of bounds
cout<<" "<<temp->data;
temp = temp->next;
}
}
thanks to user Retired Ninja for reminding me that debuggers exist.

Why it is printing only 1st value of doubly linked list and than my program is crashing

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;
}

Circular linked list: How to correct my remove node function?

I am learning circular linked list. I face a problem when calling deleteNodeByKey() to remove head node. It works for the rest of the nodes for remove. Why is it not working if remove node is head?
#include <iostream>
#include <stdlib.h>
using namespace std;
/* structure for a node */
struct node
{
int data;
struct node *next;
};
/* Function to insert a node at the begining of a Circular
linked list */
void push(struct node **head_ref, int data)
{
struct node *ptr = (struct node*)malloc(sizeof(struct node));
ptr->data = data;
ptr->next = *head_ref;
struct node *temp = *head_ref;
/* If linked list is not NULL then set the next of last node.
It is going to last node by circling 1 times.
*/
if(*head_ref != NULL){
while(temp->next != *head_ref){
temp = temp->next;
}
//set last node by ptr
temp->next = ptr;
}
else{
// 1 node circular linked list
ptr->next = ptr;
}
// after push ptr is the new node
*head_ref = ptr;
}
//get the previous node
struct node* getPreviousNode(struct node* current_node){
struct node* prev = current_node;
while(prev->next != NULL && prev->next->data != current_node->data ){
prev = prev->next;
}
return prev;
}
/* Given a reference (pointer to pointer) to the head of a list
and a key, deletes the first occurrence of key in linked list */
void deleteNodeByKey(struct node **head_ref, int key)
{
// Store head node
struct node* current_node = *head_ref, *prev;
while(current_node != NULL && current_node->data != key){
current_node = current_node->next;
}
if(current_node == NULL){
return;
}
//Removing the node
if(current_node->data == key){
prev = getPreviousNode(current_node);
prev->next = current_node->next;
current_node->next = NULL;
free(current_node);
return;
}
}
/* Function to print nodes in a given Circular linked list */
void printList(struct node *head)
{
struct node *temp = head;
if(head != NULL){
/*
do-while because at 1st temp points head
and after 1 rotation temp wil come back to head again
*/
do{
cout<<temp->data<<' ';
temp = temp->next;
}
while(temp != head);
cout<<endl;
}
}
int main() {
/* Initialize lists as empty */
struct node *head = NULL;
/* Created linked list will be 11->2->56->12 */
push(&head, 12);
push(&head, 56);
push(&head, 2);
push(&head, 11);
cout<<"Contents of Circular Linked List"<<endl;
printList(head);
deleteNodeByKey(&head, 11);
printList(head);
return 0;
}
Here is the code link: Source Code
Head node should not be the part of linked list, it should be a separate node which holds the address of the first node of the linked list. So when yo delete the first node make the Head point to the next of the first node and when you follow this structure the head-node will be same like other nodes.
declare head like this:
struct node* head;
head = *first;
To delete first
head = head->next;
free(first);`
In order to get around issues pertaining to deletion of head. I always found it useful to create a dummy node and set your head pointer to that.
node dummy;
dummy.next = *head_ref;
// Store head node
struct node* current_node = &dummy, *prev = &dummy;
current_node = current_node->next;
Once you are done with the operation set the head back to dummy.next. In this way you no longer need to keep track of the special case head, it can be treated as a normal node. Your code modified here: deletion with dummy node
inside deleteNodeByKey() function i add an if() block to re assign head node to it's next node:
//Removing the node
if(current_node->data == key){
//following if() is newly added
//key is inside head node
if(current_node == *head_ref ){
//changing the head point to next
*head_ref = current_node->next;
}
prev = getPreviousNode(current_node);
prev->next = current_node->next;
current_node->next = NULL;
free(current_node);
return;
}

Linked List Only Showing Last Value Entered

I am trying to become a little more adept with linked lists. I've watched several videos and read multiple forum posts, but I am still having issues. I am trying to start with a simple linked list. However, with my current code only the last value prints. I would really appreciate if someone could explain to me what I have done wrong. Also, I usually define all my functions in the main.cpp file. However, it would not let me do this for my linked list. Also, is defining all functions in the main.cpp file a good practice or a habit I should break?
Thanks in advance :).
Below is my linkedlist file:
#pragma once
#include <iostream>
using namespace std;
class LinkedList {
struct node {
int data;
node *next;
};
public:
LinkedList() {
head = NULL;
}
node *newNode;
node *temp;
node *head;
void insertData(int value) {
newNode = new node;
newNode->data = value;
temp = newNode;
head = newNode;
temp->next = newNode;
temp = temp->next;
newNode->next = NULL;
}
void printList() {
node *print;
print = head;
while (print != NULL) {
cout << print->data;
print = print->next;
}
}
};
Here is my main.cpp file
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main() {
LinkedList list;
list.insertData(1);
list.insertData(2);
list.insertData(3);
list.printList();
system("pause");
return 0;
}
void insertData(int value) {
newNode = new node;
newNode->data = value;
temp = newNode;
head = newNode;
temp->next = newNode;
temp = temp->next;
newNode->next = NULL;
}
In your code, head = newNode takes whatever head was pointing to, and throws it out in favor of newNode. Essentially, every time you try to insert a new value into the list, you discard the whole list.
Rather, your insert should do something like
void insertData(int value) {
newNode = new node; //Create ourselves a new node
newNode->data = value; //Put the proper value in
newNode->next = head; //Make it so the whole list is after our node
head = newNode; //Make our node the first in the list
}
There are some other things in your code I would advise changing, like the fact that you have newNode and temp as member variables when they could simply be local to the functions, and your lack of a destructor. But your print function should work with the modified insert (see it run here).

Printing Linked List in C++

My following code print just only first element. In print_list() function, it stops after printing first element. It says after first element, head->next is 0. Shouldn't point towards second element?
I want to simply print whole list.
#include<iostream>
#include<cstdlib>
using namespace std;
struct node {
int x;
node *next;
};
node* add_element(node*);
bool is_empty(node*);
void print_list(node*);
node* search(node*);
int main()
{
node *head;
head=NULL;
node* current=head;
for(int i=0;i<5;i=i+1)
{
if (current==NULL)
{
current=add_element(current);
head=current;
}
else{
current=add_element(current);
}
}
cout<<head->next<<endl;
// DOUBT: head->next gives NULL value. It should give me pointer to 2nd node
print_list(head);
}
node* add_element(node* current)
{
node* temp;
temp=new node;
temp->next=NULL;
cout<<"enter element"<<endl;
cin>>temp->x;
current=temp;
return current;
}
bool is_empty(node* temp)
{
return temp==NULL;
}
void print_list(node* temp)
{
if (is_empty(temp)==false)
{
cout<<"here temp(head)"<<temp->next<<endl;
while(temp!=NULL)
{
cout<<temp->x<<endl;
temp = temp->next;
}
}
}
Print function print first element because you have just one node in the Linked List! Actually the mistake is present in add_element(node*) function, you overwrite address of head node with new node (so having memory leak) as I marked below:
node* add_element(node* current)
{
node* temp;
temp = new node; <---" You allocated memory"
temp->next = NULL; <---" Set next NULL"
cout<< "enter element" << endl;
cin>> temp->x; <---" Assign a value in new node"
// Replace below two line with suggested
current = temp; <---"MISTAKE: Overwrite first node"
"temp next is NULL so losing address of other nodes"
return current; <--- "return first node"
}
Next of new node (so first node) is NULL hence the print function prints only first node's value.
Suggestion:
You should Correct as follows to add new node as a first node in linked list:
temp -> next = current; // new nodes next if present first node
return temp; // new code becomes first node
Be careful current should be NULL initially.
With my suggestion in add_element() function also change the for loop code in main() as follows:
for(int i=0; i < 5; i = i + 1){
current = add_element(current);
}
head = current;
And check the working code at Codepade (instead of user input I added value using y = 100 variable).
Edit To append new node:
You need to check whether new node is first node of not (read comments).
// returns first node address in linked list = head
node* add_element(node* head){
node *temp, *new_nd;
// Create new node
new_nd = new node;
new_nd->next = NULL;
cout<<"enter element"<<endl;
cin>>new_nd->x;
// Is new node is the first node?
if(!head)
return new_nd;
// move to last
temp = head;
while(temp->next) temp = temp->next;
// add new node at last
temp->next = new_nd;
// return old head
return head;
}
Also simply main() as below:
int main(){
node *head = NULL;
for(int i = 0; i < 5; i = i + 1){
head = add_element(head);
}
print_list(head);
}
check this working code.
Your problem is here:
node* add_element(node* current)
{
node* temp; //You created a new node
temp=new node; //You allocated it here
temp->next=NULL; //You set its next property to null
cout<<"enter element"<<endl; //
cin>>temp->x;
current=temp; //This should be current->next = temp. You are overwriting it!
return current; //And now you are returning essentially the temp object that
//You created and you set its next property to NULL
}
You are assigning the node you created in temp = new node to the current node that was passed in. What you want to do is assign the node you just created to the current node's next property. It should be current->next = temp
head->next is NULL because you set it so in add_element(). To have a linked list, you should set current->next = temp.
As you're using C++, you might consider using std::list instead of implementing your own linked list.
if (current==NULL)
{ current=add_element(current);
head=current;
}
else
{ current->next=add_element(current);
current=current->next;
}
The correct code.
You have to make a small correction in the loop.
You have to add a new node and then make it point to the next of the current node.
so the simplified code is current->next=add_element(current)
and then make current point to the new current.