Reversing a linked list using recursion - c++

I don't know where I'm going wrong. Output shows 1 upon inputting 1 2 3 -1 (-1 to terminate insertion of nodes). Help is appreciated!
I can't seem to find the error in my code that is resulting in wrong output upon different test cases.
Other approaches to the same problem are also welcome.
Any tips so that i won't commit such errors in the future, along with some fundamentals(generally tips) of linked lists
#include <iostream>
using namespace std;
class Node
{
public:
int data;
Node *next;
Node(int data)
{
this->data = data;
next = NULL;
}
};
Node *insert()
{
int data;
cin >> data;
Node *head = NULL;
Node *tail = NULL;
while (data != -1)
{
Node *n = new Node(data);
if (head == NULL)
{
head = n;
tail = n;
}
else
{
tail->next = n;
tail = tail->next;
}
cin >> data;
}
return head;
}
void print(Node *head)
{
Node *temp = head;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
}
Node *rev_LL(Node *head)
{
if (head == NULL || head->next == NULL)
{
return head;
}
Node *smallAns = rev_LL(head->next);
Node *temp = smallAns;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = head;
head->next = NULL;
return smallAns;
}
int main()
{
Node *head = insert();
print(head);
cout << endl;
cout << "After reversing the Linked list : " << endl;
rev_LL(head);
print(head);
cout << endl;
return 0;
}

You have to assign the return value of rev_LL to head instead of just ignoring that.
int main()
{
Node *head = insert();
print(head);
cout << endl;
cout << "After reversing the Linked list : " << endl;
//rev_LL(head);
head = rev_LL(head); // assign the result
print(head);
cout << endl;
return 0;
}

Related

Insert at end not working on NULL head in c++ linked list [duplicate]

This question already has an answer here:
How to pass head from main to addNode function ? (LinkedList implementation via struct)
(1 answer)
Closed 1 year ago.
My Cpp File code
#include <bits/stdc++.h>
using namespace std;
class Node
{
public:
int data;
Node *next;
};
void insert_at_end(Node *head, int data)
{
Node *temp = new Node();
temp->data = data;
temp->next = NULL;
if (head == NULL)
{
head = temp;
// cout << temp->data << " " << " : " << head->data << endl ;
}
else
{
Node *last = head;
while (last->next != NULL)
{
last = last->next;
}
last->next = temp;
cout << "Inserted " << data << " at the End \n";
}
}
void printList(Node *head)
{
cout << "List : \n";
Node *temp = head;
if (temp == NULL)
cout << "Forgive me !";
while (temp != NULL)
{
cout << "\t" << temp->data << "";
temp = temp->next;
}
}
int main()
{
Node *head = NULL;
insert_at_end(head, 12);
insert_at_end(head, 16);
insert_at_end(head, 71);
insert_at_end(head, 81);
insert_at_end(head, 91);
printList(head);
return 0;
}
It works fine if Head is not NULL ( If already have inserted value at start of list) but as you can see Head is NULL in start it gives a error , Probably the error is in insert_at_end function .
I think i am missing some concept of pointers
the problem with your code is that the function insert_at_end is taking a pointer to the head, meaning it can't modify the head pointer itself.
You could make it this way though :
void insert_at_end(Node **head, int data)
{
Node *temp = new Node();
temp->data = data;
temp->next = NULL;
if (*head == NULL)
{
*head = temp;
}
else
{
Node *last = *head;
while (last->next != NULL)
{
last = last->next;
}
last->next = temp;
cout << "Inserted " << data << " at the End \n";
}
}

Can't stop taking input and get the flow inside while loop?

I am trying to implement Linked list in c++ and cannot seem to get that why I can't stop taking input from the terminal.
Node* take_input_better() {
int data;
cin >> data;
Node *head = NULL;
Node *tail = NULL;
while(data != -1) {
cout << "debug" << endl;
Node *newNode = new Node(data);
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail -> next = newNode;
tail = tail -> next;
// OR
// tail = newNode;
}
cout << "Debug" << endl;
cin >> data;
}
return head;
}
This function just creates a linked list with the element until -1 is entered.
If I enter the first element as -1. it seems to work fine. But when it is not -1 after I have already entered some data the program seem to take infinite number of inputs and the flow isn't even inside the while statement as the words "debug" and "Debug" don't get printed.
Edit 1: Here's the Full Program
Node.cpp
class Node {
public:
int data;
Node *next;
Node(int data){
this->data = data;
next = NULL;
}
};
linked_list.cpp
#include <iostream>
using namespace std;
#include "Node.cpp"
Node* take_input_better() {
int data;
cin >> data;
Node *head = NULL;
Node *tail = NULL;
while(data != -1) {
cout << "debug" << endl;
Node *newNode = new Node(data);
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail -> next = newNode;
tail = tail -> next;
// OR
// tail = newNode;
}
cout << "Debug" << endl;
cin >> data;
}
return head;
}
int length(Node *head){
Node *temp = head;
int count = 0;
while(temp != NULL){
count++;
}
return count;
}
int main(){
Node *head = take_input_better();
cout << "Length of the Linked List: " << length(head) << endl;
}
The error is in the length function. You are not moving the temp pointer forward. Do this:
int length(Node *head){
Node *temp = head;
int count = 0;
while(temp != NULL){
count++;
temp = temp->next;
}
return count;
}
Get familiar with the debugger. It is your friend.
You also need to make sure the input stream is in a readable state (e.g. cin.good()). If it goes into a fail state, cin >> data will keep going, but without waiting for new user input or putting any meaningful value into data.

inserting node in the beginning of linked list using codeblocks

when i am inserting node in the beginning of the linked list, node is inserted in the beginning and is displayed. if i call display separately then it does not work and for inserting node at specific loc and at the end, calling display function works well.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct node {
int data;
struct node* next;
} node;
node* create(int n)
{
node* temp = NULL;
node* head = NULL;
node* p;
int i;
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
cout << "enter the data for node number " << i << endl;
cin >> temp->data;
temp->next = NULL;
if (head == NULL) {
head = temp;
}
else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
return head;
}
node* insertatbeg(node* head)
{
node* temp = NULL;
temp = (node*)malloc(sizeof(node));
cout << "\nenter the data for first node" << endl;
cin >> temp->data;
temp->next = head;
head = temp;
return head;
}
void display(node* head)
{
node* t = NULL;
t = head;
while (t != NULL) {
cout << t->data << "->";
t = t->next;
}
}
node* insertatspecloc(node* head)
{
int n;
node* temp = NULL;
node* t = head;
temp = (node*)malloc(sizeof(node));
cout << "enter the data of node after which you want to insert the
node "<<endl;
cin
>> n;
cout << "\nenter the data for last node" << endl;
cin >> temp->data;
while (t->data != n) {
t = t->next;
}
temp->next = t->next;
t->next = temp;
return head;
}
node* insertatend(node* head)
{
node* temp = NULL;
temp = (node*)malloc(sizeof(node));
cout << "\nenter the data for last node" << endl;
cin >> temp->data;
temp->next = NULL;
node* q;
q = head;
while (q->next != NULL) {
q = q->next;
}
q->next = temp;
return head;
}
int main()
{
int n, a;
struct node* head = NULL;
cout << "enter the number of nodes u want to add";
cin >> n;
head = create(n);
display(head);
cout << "\npress 1 to add node at the beginning";
cout << "\npress 2 to add node at the specific location";
cout << "\npress 3 to add node at the end\n";
cin >> a;
if (a == 1) {
insertatbeg(head);
cout << "\nlinked list after insertion:\n";
display(head);
}
if (a == 2) {
insertatspecloc(head);
cout << "\nlinked list after insertion:\n";
display(head);
}
if (a == 3) {
insertatend(head);
cout << "\nLinked list after insertion:\n";
display(head);
}
}
When you are calling insertatbeg(head); the copy of head pointer is passed as the argument of your function, then in function you are modyfing local variable (copy of head)
node *insertatbeg(node *head)
{
node *temp=NULL;
temp=(node*)malloc(sizeof(node));
cout<<"\nenter the data for first node"<<endl;
cin>>temp->data;
temp->next=head;
head=temp; // assign to local variable <---
return head;
}
and for this reason after executing insertatbeg head is not updated. insertatbeg returns pointer so you can resolve your issue by calling
head = insertatbeg(head);
or you can call function in above line without assigning but then you should pass head by reference to be able to modify original passed object in function:
node *insertatbeg(node *& head) // pass pointer by reference
{
node *temp=NULL;
//...
head = temp; // now it works

Making a circular linked list and finding the beginning of the loop

my assignment is to find the beginning of a loop in a circular linked list. Since the list is not provided i decided to make a liat by getting the user input for the size of the list then run a for loop with that size. The very last input (last node) is going to point somewhere in the linked list to create a cycle. My function to create the linked list is working, if i cout the head->data while getting the input from the user it prints the right value but when i call the function in the main the head pointer points to NULL and i get a segmentation fault. Can someone take a look at my code and explain why something like that is happening?
#include <iostream>
using namespace std;
struct node{
int data;
node *next;
};
node *head = NULL;
node *tail = NULL;
node *slow = NULL;
node *fast = NULL;
int findLoop(node * head);
void getList(node * head, int listSize);
bool isEmpty(node * head);
int main(){
int listSize;
cout <<"\nEnter the size of the list: ";
cin >> listSize;
getList(head, listSize);
if(head != NULL){
cout << "\n\n\nprinting head " << head->data; //Seg Fault
}
else{
cout << "Head is NULL" << endl;
}
findLoop(head);
return 0;
}
int findLoop(node *head){
slow = head;
fast = head;
if(head == NULL){
cout << "\nThe list is empty\n";
}
bool isLoop = false;
while(slow != NULL && fast != NULL){
if(slow == fast && isLoop == false){
slow = head;
isLoop = true;
}
else if(slow == fast && isLoop == true){
cout <<"\nThe loop starts at: ";
return slow->data;
}
slow = slow->next;
fast = fast->next->next;
}
cout <<"\nThere is no loop\n";
return 0;
}
void getList(node * head, int listSize){
int userData;
for(int i=0; i<listSize; i++){
node *temp = new node;
cout <<"\nEnter a number: ";
int NodeValue = 0;
cin >> NodeValue;
temp->data = NodeValue;
if(head == NULL){
head = temp;
cout << head->data << endl; //Test for appropriate pointing.
}
if(tail != NULL){
tail->next = temp;// point to new node with old tail
}
tail = temp;// assign tail ptr to new tail
temp->next = tail;
if(i == listSize-1){
node *temp2;
temp2 = head;
int iNumber = rand() % i;
for(int j=0; j<iNumber; j++){
temp2 = temp2->next;
}
tail->next = temp2;
}
}
}
Minimal change to actually return new list would be passing pointer by reference:
void getList(node*&, int );
or better do define pointer type
using nodePtr = node*;
void getList(nodePtr&, int);

Linked List Crashes after all nodes are deleted

Our homework assignment wanted us to create a "Staque" (implements features of a stack and a queue) using a linked list. When entering even numbers in the list, they should go to the top of the list and odd numbers at the bottom. So if the values inserted are 8 1 4 6 7 9 it should output 6 4 8 1 7 9. Then you delete the top two even numbers and the bottom odd number which would give 8 1 7. Everything seems to work fine except when all the nodes are deleted so when you enter 3 or less values, the program crashes. At this time I have to turn in my assignment since it's due tonight but am just wondering how this can be resolved. Any help would be appreciated.
Here is my code:
Driver:
#include <iostream>
#include "Staq.h"
using namespace std;
int main()
{
Staq *std = new Staq();
int numofvals;
int i;
int x;
cout << "How many values in the staque?" << endl;
cin >> numofvals;
cout << numofvals << " values will be entered in the staque." << endl << endl;;
for(i=1; i<=numofvals; i++)
{
cout << "Enter value " << i << ":" << endl;
cin >> x;
std->AddNode(x);
}
cout << endl;
cout << "Staque:" << endl;
std->PrintList();
std->DeleteNode();
cout << "\nStaque after deletions:" << endl;
std->PrintList();
return 0;
}
.CPP:
#include <iostream>
using namespace std;
#include "Staq.h"
Staq::Staq()
{
head = NULL;
curr = NULL;
temp = NULL;
}
void Staq::AddNode(int addData)
{
nodePtr n = new node;
n->next = NULL;
n->data = addData;
if(addData % 2 == 0)
{
if(head == NULL)
{
head = n;
curr = n;
}
else
{
n->next = head;
head = n;
}
}
else
{
if(head == NULL)
{
head = n;
curr = n;
}
else
{
temp = head;
while(temp->next != NULL)
{
temp = temp->next;
}
temp->next = n;
}
}
}
void Staq::DeleteNode()
{
nodePtr temp2 = new node;
if(head->data %2 == 0)
{
temp = head;
head = head->next;
delete temp;
if(head->data %2 == 0)
{
temp = head;
head = head->next;
delete temp;
}
}
temp = head;
while(temp->next->next != NULL)
{
temp = temp->next;
}
if(temp->data %2 != 0)
{
temp2 = temp->next;
temp->next = NULL;
delete temp2;
}
}
void Staq::PrintList()
{
curr = head;
while(curr != NULL)
{
cout << curr->data << endl;
curr = curr->next;
}
}
Header:
#include <iostream>
using namespace std;
#ifndef STAQ_H
#define STAQ_H
class Staq
{
public:
Staq();
~Staq();
void AddNode(int addData);
void DeleteNode();
void PrintList();
private:
class node
{
public:
int data;
node* next;
};
typedef class node* nodePtr;
nodePtr head;
nodePtr curr;
nodePtr temp;
};
#endif
In DeleteNode, you attempt to access the first node's data, even if there isn't a node. Same goes for the second node.
while(temp->next->next) is dangerous because temp->next could be NULL therefore making temp->next->next an access to null pointer. I assume you meant temp->next. You might want to validate temp too.
Finally, although unrelated, temp2 = temp->next causes a memory leak because now no one points to the new node created at the beginning of DeleteNode.