Copy the reverse of a linked list - c++

copyRev
void copyRev(node *head1, node *&head2)
{
stack<int> dat;
node* curr = head1;
while(curr!=NULL){
dat.push(curr->data);
curr = curr->next;
}
while(!dat.empty()){
append(head2,dat.top());
dat.pop();
}
}
append
void append(node* &head, int data){
if(head==NULL){
head= new node;
head->data = data;
head->next = NULL;
}
else{
node *curr = head;
while((curr)->next!=NULL){
(curr) = (curr)->next;
}
(curr)->next = new node;
(curr) = (curr)->next;
(curr)->data = data;
(curr)->next = NULL;
}
}
Well, I'm trying to clone the reverse of a linked list. I know how to reverse a list in place. But this code gives me a Bus error(code dumped).
This is how I call the function in main()
node *head;
for(int i = 0;i<9;i++){
append(head,i*i);
}
node *revHead;
printList(head);
copyRev(head,revHead);
printList(revHead);
in append() function, I check for NULL head and create a new node if it is NULL. moreover, the append function properly adds the elements to the list. The problem arose only after I called the copyRev procedure.
I have tried in-place reversing and it works. I need to clone the reverse of a linked list. Both Iterative and Recursive solutions are welcome. Also please point out the error in the above code.
This is my own practice problem but not a homework problem

You are not initializing your pointers:
node *head;
node *revHead;
As a result they have indeterminate values (ie they are random).
Using the values in these poitners in any way is undefined behavior. Which can be your error.
Just initialize them:
node* head = NULL;
node* revHead = NULL;
Recursive reverse of a linked list in place:
void reverse(node*& head)
{
head = reverse(head, NULL);
}
node* reverse(node* item, node* next)
{
if (item == NULL)
{ return next;
}
node* iter = item->next;
item->next = next;
return reverse(iter, item);
}

at first glance you forgot to initialize the list head:
node *head = 0;
edit thanks to Alan: and revHead too

Related

Why this function is not able to reverse the Linked List?

I want to reverse a linked list but when i compile this code it terminates unexpectedly.
#include <bits/stdc++.h>
using namespace std;
class node{
public:
int data;
node* next;
node(int val){
data=val;
next=NULL;
}
};
For Inserting Elements in Linked List
void insertattail(node* &head,int lol){
node* n= new node(lol);
if(head==NULL){
head=n;
return;
}
node* temp=head;
while(temp->next!=NULL){
temp=temp->next;
}
temp->next=n;
}
Display Function to print linked list
void display(node* head){
node* temp =head;
do{
cout<<temp->data<<"->";
temp=temp->next;
}
while(temp!=NULL);
cout<<"Null";
}
Function to reverse Linked List
node* reverseit(node* head){
node* prevptr= NULL;
node* currptr= head;
node* nextptr= currptr->next;
while(currptr!=NULL){
currptr->next =prevptr;
prevptr=currptr;
currptr=nextptr;
nextptr=currptr->next;
}
return prevptr;
}
Main Function
int main()
{
node* head= NULL;
insertattail(head,1);
insertattail(head,2);
insertattail(head,3);
insertattail(head,8);
node* newhead= reverseit(head);
display(newhead);
return 0;
}
I think the problem is in logic of reverse function.
I just used the code for linked list and made small changes.
Your initialization and 'incrementing' of nextptr both (potentially/eventually) dereference a NULL value of currptr. You should initialize nextptr to NULL and only change that to the 'real' next if currptr is not NULL; thus, its (re)assignment should be at the start of the loop, not at the end:
node* reverseit(node* head){
node* prevptr = nullptr;
node* currptr = head;
node* nextptr = nullptr; // Don't assume a non-NULL currptr
while (currptr != nullptr) {
nextptr = currptr->next; // Safe here: save next
currptr->next = prevptr; // Do the reversal here
prevptr = currptr; // Step forward through
currptr = nextptr; // the list (prev/curr)
// nextptr = currptr->next; // WRONG HERE: currptr will be NULL at some point
}
return prevptr;
}
The function invokes undefined behavior.
For example let's at first assume that the list is empty. That is the pointer head is equal to nullptr. In this case using this line before the while loop within the function
node* nextptr= currptr->next;
accesses memory using a null pointer.
Or let's consider another example when current->next is equal to nullptr. In this case nextptr will be equal to nullptr and within the while loop these statements
currptr=nextptr;
nextptr=currptr->next;
again access memory using a null pointer.
And declarations of many pointers before the while loop
node* prevptr= NULL;
node* currptr= head;
node* nextptr= currptr->next;
makes the code less readable and clear.
The function can be defined the following way
node * reverseit( node *head )
{
node *new_head = nullptr;
for ( node *current = head; head != nullptr; head = current )
{
current = head->next;
head->next = new_head;
new_head = head;
}
return new_head;
}
If actually your program is a C program then instead of nullptr use NULL.
Also in main there is no need to introduce the new pointer newhead
node* newhead= reverseit(head);
You could just write
head = reverseit(head);
The function display can again invoke undefined behavior if the passed pointer to the head node is equal to nullptr. And the parameter of the function should have the qualifier const because within the function the list itself is not changed.
The function can be defined the following way
std::ostream & display( const node *head, std::ostream &os = std::cout )
{
for ( const node *current = head; current != nullptr; current =current->next )
{
os << current->data << " -> ";
}
return os << "Null";
}
And the function can be called like
display( head ) << '\n';

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.

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

print linked list error. What's wrong?

struct Node
{
int data;
struct Node *next;
};
Node *AppendNode(Node *head, int data) {
Node *ptr = head;
struct Node node = {data, ptr->next};
head->next = &node;
return head;
}
void PrintNode(Node *head) {
Node *ptr = head;
while (ptr != 0) {
printf("%d ", ptr->data);
ptr = ptr->next;
}
}
int main() {
Node node = {1 , 0};
Node* head = &node;
head = AppendNode(head, 2);
PrintNode(head);
return 0;
}
Output is (1,3830) instead of (1,2). Check debuggers I saw node value changes from 2 to 3830 in this step ptr = ptr->next; inside PrintNode. Sorry I am new to C++.
This is wrong:
Node *AppendNode(Node *head, int data) {
Node *ptr = head;
struct Node node = {data, ptr->next};
head->next = &node;
return head;
}
You are inserting a pointer to a local stack variable into your linked list. As soon as your function returns, the memory referenced by &node is going to be clobbered pretty soon.
Also, whatever head->next was previously pointing to before the assignment is getting leaked (and lost).
Better:
Node* AppendNode(Node *head, int data)
{
Node* newNode = new Node;
newNode->data = data;
newNode->next = head;
head = newNode;
return head;
}
But technically the above is "prepending" to the list, not "appending" as your function signature suggests. Maybe that's what you want, but if not, that's an exercise I'll leave up to you. :)
As the other answer from Bo mentions, don't forget to call "delete" on your nodes when you are done with the list to avoid the memory leak.
You have a local Node in AppendNode. As soon as you leave the function, that node is gone.
If you must create nodes dynamically, you do that with new Node. Just don't forget to delete the nodes later.

Where is the Error in following code snippet, I have made a linkedlist implementation and I am adding elemnts at tail of the LinkedList

I have made a simple linkedlist implementation and I am getting this error on when I am running the code at Insert() function call in Main(), I dont understand Why so.
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
};
struct Node* head;
int main(){
head=NULL;
Insert(1,2);
Insert(2,1);
Insert(3,1);
Insert(4,1);
}
void Print(){
struct Node* temp;
temp=head;
while(temp!=NULL){
printf("%d ",tenp->data);
temp=temp->next;
}
printf("\n");
}
Node* Insert(Node *head,int data)
{
Node *node = new Node();
node->data = data; // ASSIGNING VALUES TO NEW NODE
node->next = NULL; // ALSO AS TO ACT AS THE TAIL NODE ADDING THE null VALUE AT THE NEXT POINTER
if(head == NULL) // CASE: WHEN LIST IS EMPTY
return node;
Node *temp = head; // dereferencing value for TEMP, assignning it the HEAD values, HEAD is the current tail node
while(temp->next != NULL) // Traversing till 1 before
temp = temp->next;
temp->next = node; // making the last move, assigning the LINK to new node.
return head; // returinng the funn call with VALUE
}
Insert(1,2)//this won't work as insert()
//expects node* type and not an integer as first argument.
You should pass the pointer to head instead of the value.
You are passing 1,2,3 and 4 into a Node* argument.
You have to pass the actual head node and assign the result,
head = Insert( head, value );
Thats how you made the function to be used.