Reversing singly linked list using recursion - c++11

I have written code to reverse singly linked list using recursion. It is working fine on lists of length less than or equal to 174725. But on lists of length greater than 174725 it gives a segmentation fault(Segmentation fault: 11) while reversing it via reverse() call. Can someone please explain this to me ?
#include <iostream>
using namespace std;
class Node
{
public:
int val;
Node *next;
};
class Sll
{
public:
Node *head;
private:
void reverse(Node *node);
public:
Sll();
void insert_front(int key);
void reverse();
void print();
};
void Sll::reverse(Node *node)
{
if (node == NULL) return;
Node *rest = node->next;
if (rest == NULL)
{
head = node;
return;
}
reverse(rest);
rest->next = node;
node->next = NULL;
return;
}
Sll::Sll()
{
head = NULL;
}
void Sll::insert_front(int key)
{
Node *newnode = new Node;
newnode->val = key;
newnode->next = head;
head = newnode;
return;
}
void Sll::print()
{
Node *temp = head;
while (temp)
{
temp = temp->next;
}
cout << endl;
return;
}
void Sll::reverse()
{
reverse(head);
return;
}
int main()
{
Sll newList = Sll();
int n;
cin >> n;
for (int i = 0; i < n; i++) newList.insert_front(i + 1);
newList.reverse();
// newList.print();
return 0;
}

List reversing function must be tail-recursive, otherwise it is going to overflow the stack when recursing over a long list, like you observe. Also, it needs to be compiled with optimisations enabled or with -foptimize-sibling-calls gcc option.
Tail-recursive version:
Node* reverse(Node* n, Node* prev = nullptr) {
if(!n)
return prev;
Node* next = n->next;
n->next = prev;
return reverse(next, n);
}
An iterative list reversion can be more easily inlined though and it does not require any optimization options:
inline Node* reverse(Node* n) {
Node* prev = nullptr;
while(n) {
Node* next = n->next;
n->next = prev;
prev = n;
n = next;
}
return prev;
}

Related

Find the Error or memory leak

I was writing LinkedList Program in C++
Here is the Code. Find the Error and Memory Leak or anything else.
I want to write a perfect code.
#ifndef LEARN_REVERSELINKLIST_H
#define LEARN_REVERSELINKLIST_H
#include <string>
#include <utility>
#include <iostream>
#include <boost/assert.hpp>
class ReverseLinkList {
private:
struct Node {
std::string string;
Node *Previous{};
Node *Next{};
};
Node *head;
Node *tail;
int count;
public:
ReverseLinkList();
~ReverseLinkList();
void insert(std::string string);
void insertAt(std::string string, int position);
void iterator() const;
void reverseIterator() const;
void remove(const std::string &string);
void removeAt(int position);
int size() const;
Node *getHead() const;
Node *getTail() const;
};
#endif //LEARN_REVERSELINKLIST_H
and Here is the CC File
#include "ReverseLinkList.h"
ReverseLinkList::~ReverseLinkList() {
if (count != 0) {
Node *temp = head;
while (temp != tail->Next) {
delete temp->Previous;
temp = temp->Next;
}
tail = nullptr;
head = nullptr;
}
}
ReverseLinkList::ReverseLinkList()
: head(nullptr), tail(nullptr), count(0) {
}
void ReverseLinkList::iterator() const {
BOOST_ASSERT_MSG(count != 0, "List is empty");
Node *temp;
temp = head;
while (temp != tail->Next) {
std::cout << temp->string << std::endl;
temp = temp->Next;
}
}
void ReverseLinkList::reverseIterator() const {
BOOST_ASSERT_MSG(count != 0, "List is empty");
Node *temp;
temp = tail;
while (temp != head->Previous) {
std::cout << temp->string << std::endl;
temp = temp->Previous;
}
}
void ReverseLinkList::insert(std::string string) {
auto *newNode = new Node;
newNode->string = std::move(string);
count++;
if (head == nullptr && tail == nullptr) {
newNode->Previous = nullptr;
newNode->Next = nullptr;
head = newNode;
tail = newNode;
} else {
tail->Next = newNode;
newNode->Next = nullptr;
newNode->Previous = tail;
tail = newNode;
}
}
int ReverseLinkList::size() const {
return count;
}
void ReverseLinkList::remove(const std::string &string) {
BOOST_ASSERT_MSG(count != 0, "List is empty");
if (count == 1) {
if (head->string == string) {
delete head;
head = nullptr;
tail = nullptr;
}
count--;
return;
}
if (head->string == string) {
Node *temp;
temp = head->Next;
delete head;
head = temp;
head->Previous = nullptr;
count--;
return;
}
if (tail->string == string) {
Node *temp;
temp = tail->Previous;
delete tail;
tail = temp;
temp->Next = nullptr;
count--;
return;
}
Node *temp;
temp = head;
bool verbose = true;
while (temp != tail->Next) {
if (temp->string == string) {
verbose = false;
break;
}
temp = temp->Next;
}
if (verbose) {
std::cerr << "Node not present" << std::endl;
return;
}
Node *previous, *next;
previous = temp->Previous;
next = temp->Next;
delete temp;
previous->Next = next;
next->Previous = previous;
count--;
}
void ReverseLinkList::insertAt(std::string string, int position) {
if (position > count)
return;
if (position == 0) {
if (head == nullptr) {
insert(string);
return;
}
auto *newNode = new Node;
newNode->string = string;
newNode->Previous = nullptr;
head->Previous = newNode;
newNode->Next = head;
head = newNode;
count++;
return;
}
if (position == count - 1) {
insert(string);
return;
}
Node *temp;
temp = head;
while (position != 0) {
temp = temp->Next;
position--;
}
Node *next;
next = temp->Next;
auto *newNode = new Node;
newNode->string = string;
temp->Next = newNode;
newNode->Previous = temp;
newNode->Next = next;
next->Previous = newNode;
count++;
}
ReverseLinkList::Node *ReverseLinkList::getHead() const {
return head;
}
ReverseLinkList::Node *ReverseLinkList::getTail() const {
return tail;
}
void ReverseLinkList::removeAt(int position) {
BOOST_ASSERT_MSG(count != 0, "List is empty");
if (position > count)
return;
Node *temp;
if (count == 1) {
delete head;
head = nullptr;
tail = nullptr;
count--;
return;
}
if (position == 0) {
temp = head->Next;
delete head;
head = temp;
head->Previous = nullptr;
count--;
return;
}
if (position == count) {
temp = tail->Previous;
delete tail;
tail = temp;
tail->Next = nullptr;
count--;
return;
}
temp = head;
while (position != 0) {
temp = temp->Next;
position--;
}
Node *previous;
Node *next;
previous = temp->Previous;
next = temp->Next;
delete temp;
previous->Next = next;
next->Previous = previous;
count--;
}
I would like to have some suggestion how can I write better code and Implement it. If you have some functions you would like to add please do post.
My next move is to make this code using templates

How to store an array of LinkedList heads in C++?

Given a binary tree, I'm trying to make a linked list of elements for each depth. That makes D lists for depth D. I'm doing a non-recursive implementation and using level order traversal in my C++ code. Though I don't see any error while compilation, I know that my heads are not storing in the array of pointers. Please have a look at my code. Any help or suggestion would be great since I'm new to data structures. Thanks!
#include <iostream>
#include <queue>
using namespace std;
struct BTnode
{
int data;
BTnode* left;
BTnode* right;
};
struct LLnode
{
int data;
LLnode* next;
};
BTnode* newNode(int data)
{
BTnode* node = new BTnode;
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
void MakeLL(LLnode* &head, int data)
{
LLnode* temp = new LLnode;
temp->data = data;
if (head == NULL)
{
head = temp;
temp->next = NULL;
}
else
{
temp->next = head;
head = temp;
}
}
LLnode** LevelElementsLinkedlist(BTnode* &root)
{
if (root == NULL)
return NULL;
queue<BTnode*>nodeQ;
nodeQ.push(root);
int level = 0;
LLnode **arr;
while(1)
{
int count = nodeQ.size();
if (count == 0)
break;
LLnode* head = NULL;
arr[level] = head;
level ++;
while (count > 0)
{
BTnode* node = nodeQ.front();
MakeLL(head,node->data);
nodeQ.pop();
if (node->left)
nodeQ.push(node->left);
if (node->right)
nodeQ.push(node->right);
count--;
}
}
return arr;
}
void printLL(LLnode* head)
{
if (head == NULL)
return;
LLnode* temp = head;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
}
int main()
{
BTnode* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(40);
root->left->right = newNode(5);
root->right->left = newNode(60);
root->right->right = newNode(7);
root->left->left->left = newNode(8);
root->left->left->right = newNode(9);
root->left->right->left = newNode(10);
root->left->right->right = newNode(11);
root->right->left->left = newNode(12);
root->right->left->right = newNode(13);
root->right->right->left = newNode(14);
root->right->right->right = newNode(15);
LLnode** arr = LevelElementsLinkedlist(root);
int n = sizeof(arr)/sizeof(arr[0]);
cout << n;
for (int i = 0; i < n; i++)
{
printLL(arr[i]);
cout << endl;
}
cout << endl;
return 0;
}
There are a few problem that I noticed in your code.
In the function LevelElementsLinkedlist, you are not allocating space for arr. It should be LLnode *arr = new LLnode *[100].
Check the line where you have written the following:
LLnode* head = NULL;
arr[level] = head;
You are assigning NULL to head and then adding it to the array. Your whole array will contain nothing else but NULLs.
Try fixing these issues and try executing your code again.

Binary Search Tree Traversals

I have just started learning Binary Trees and went ahead and tried to implement my own in C. I am kinda lost as to why only InOrder Traversal is displaying correctly while the other two are wrong. I really can't figure this out. I even directly tried inserting nodes, and the result is the same.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct Node
{
int val;
struct Node *left;
struct Node *right;
};
//Allocate Memory for New Node
struct Node* getNewNode(int val)
{
struct Node * ptr = (struct Node*)malloc(sizeof(struct Node));
ptr->val = val;
ptr->left = NULL;
ptr->right = NULL;
return ptr;
}
//Insert Node in Binary Search Tree
struct Node* insertNode(struct Node* root,int val)
{
if(root == NULL)
{
root = getNewNode(val);
}
else if(val <= root->val)
{
root->left = insertNode(root->left,val);
}
else
{
root->right = insertNode(root->right,val);
}
return root;
}
void printInorder(struct Node* root)
{
if(root == NULL) return;
printInorder(root->left);
printf("%d ",root->val);
printInorder(root->right);
}
void printPostOrder(struct Node* root)
{
if(root == NULL) return;
printInorder(root->left);
printInorder(root->right);
printf("%d ",root->val);
}
void printPreOrder(struct Node*root)
{
if(root == NULL) return;
printf("%d ",root->val);
printInorder(root->left);
printInorder(root->right);
}
bool search(struct Node* root,int val)
{
if(root == NULL)
{
return false;
}
else if(val == root->val)
{
return true;
}
else if(val < root->val)
{
return search(root->left,val);
}
else
{
return search(root->right,val);
}
}
int main(void)
{
struct Node * root = NULL; //Tree is Empty
root = insertNode(root,15);
root = insertNode(root,10);
root = insertNode(root,8);
root = insertNode(root,12);
root = insertNode(root,20);
root = insertNode(root,17);
root = insertNode(root,25);
printf("Printing In-Order: \n");
printInorder(root);
printf("\nPrinting Post-Order: \n");
printPostOrder(root);
printf("\nPrinting Pre-Order: \n");
printPreOrder(root);
// if(search(root,11))
// {
// printf("\nValue Found\n");
// }
// else
// {
// printf("\nValue Not Found\n");
// }
return 0;
}
Please help me understand if I am doing this wrong or my understanding of traversals is faulty.
The output is as follows:
output terminal
You have copy-paste errors in printPostOrder and printPreOrder - they both call printInorder where they should be calling themselves.

Trying to insert an Avl tree

I am trying to make an insertion method for an Avl tree but the structure and order of my nodes turns out to be incorrect. I am having trouble finding where i am going wrong.
Here are my methods
Any sort of help would be appreciated
template
void AvL<T>::insert(string val, T k)
{
if (head == NULL) {
head = new AvLNode<T>(val, k);
} else {
put(head, val, k);
}
}
template <class T>
void AvL<T>::put(AvLNode<T>* root,string val,T key1) {
if (root->key > key1) {
if (root->left != NULL) {
put(root->left, val, key1);
Balance(root, key1);
} else {
root->left = new AvLNode<T>(val, key1);
root->bf = nodeHeight(root->left) - nodeHeight(root->right);
root->left->parent = root;
}
} else {
if (root->right != NULL) {
put(root->right, val, key1);
Balance(root, key1);
} else {
root->right = new AvLNode<T>(val, key1);
root->bf = nodeHeight(root->left) - nodeHeight(root->right);
root->right->parent = root;
}
}
}
template<class T>
void AvL<T>::Balance(AvLNode<T>* root, T key1)
{ root->bf = nodeHeight(root->left) - nodeHeight(root->right);
if (root->bf < -1 && key1 > root->right->key) {
cout << "here1 ";
LeftRotate(root);
} else if (root->bf > 1 && key1 < root->left->key) {
cout << "here2 ";
RightRotate(root);
} else if (root->bf < -1 && key1 < root->right->key) {
RightRotate(root->right);
cout << "here3 ";
LeftRotate(root);
} else if (root->bf > 1 && key1 > root->left->key) {
LeftRotate(root->left);
cout << "here4 ";
RightRotate(root);
}
}
template<class T>
void AvL<T>::RightRotate(AvLNode<T>* node)
{
AvLNode<T>* node1 = node->left;
node->left = node1->right;
node1->right = node;
node->bf = nodeHeight(node->left) - nodeHeight(node->right);
node1->bf = nodeHeight(node1->left) - nodeHeight(node1->right);
node = node1;
}
template<class T>
void AvL<T>::LeftRotate(AvLNode<T>* node)
{
AvLNode<T>* node1 = node->right;
node->right = node1->left;
node1->left = node;
node->bf = nodeHeight(node->left) - nodeHeight(node->right);
node1->bf = nodeHeight(node1->left) - nodeHeight(node1->right);
node = node1;
}
template<class T>
int AvL<T>::nodeHeight( AvLNode<T> *n)
{
int lheight=0;
int rheight=0;
int h = 0;
if (n == NULL)
{
return -1;
} else {
lheight = nodeHeight(n->left);
rheight = nodeHeight(n->right);
h = 1+max(lheight,rheight);
return h;
}
}
My .h file
template <class T>
struct AvLNode
{
string value;
T key;
AvLNode *parent; // pointer to parent node
AvLNode *left; // pointer to left child
AvLNode *right; // pointer to right child
int bf; // Balance factor of node
AvLNode(string Val, T k)
{
this->value = Val;
this->key = k;
this->parent = NULL;
this->left = NULL;
this->right = NULL;
bf = 0;
}
};
template <class T>
class AvL
{
AvLNode<T> *head;
public:
// Constructor
AvL();
// Destructor
~AvL();
// Insertion Function
void insert(string val, T k); // inserts the given key value pair into the tree
void Balance(AvLNode<T>* node, T key1);
void delete_node(T k); // deletes the node for the given key
void RightRotate(AvLNode<T>* node);
void LeftRotate(AvLNode<T>* node);
void put(AvLNode<T>* root,string val,T key1);
int nodeHeight(AvLNode<T> *n); // returns height of the subtree from given node
};
Your balance function is wrong. Since you've already inserted your new node into the tree, you don't need to worry about the key any more in Balance() - so the prototype should look like this:
template<class T>
void AvL<T>::Balance(AvLNode<T>* root);
The way you're doing it now seems to be attempting to balance based on the key you just inserted - which isn't necessary! You can balance the tree just based on the balance factors of nodes - here's how.
template<class T>
void AvL<T>::Balance(AvLNode<T>* root) {
if (root->bf > 1) {
if (root->left->bf == -1) LeftRotate(root->left);
RightRotate(root);
} else if (root->bf < -1) {
if (root->right->bf == 1) RightRotate(root->right);
LeftRotate(root);
}
}
You can read more about it here - but you seem to have the idea almost down. The only thing you need to change conceptually is the idea that you're balancing based on the key you just inserted. You're not - you're balancing based on the shape of the tree, which you can get from just the balance factors of each subtree.

Add two big numbers represented as linked lists without reversing the linked lists

Suppose you have 2 big numbers represented as linked lists, how do you add them and store the result in a separate linked list.
eg
a = 2 -> 1 -> 7
b = 3 -> 4
result = 2 -> 5 -> 1
Can you add them without reversing the linked lists
Pseudocode:
Step 1. Traverse the linked lists and push the elements in two different stacks
Step 2. Pop the top elements from both the stacks
Step 3. Add the elements (+ any carry from previous additions) and store the carry in a temp variable
Step 4. Create a node with the sum and insert it into beginning of the result list
I think this's something beyond context but can be very performance incentive for the person who originally posted this question.
So here's a recommendation:
instead of using every node as a single digit of the number, use each node to store a large number(close to the size of integer) and if the highest possible number you chose to store in each node be x(your case 9) then you can view your number as a representation in base x+1.
where each digit is a number between 0 and x.
This would give you significant performance gain as the algorithm would run in O(log n) time and require the same number of nodes as against O(n) in your case , n being the number of decimal digits of the larger of two addends.
Typically for the ease of your algorithm, you can choose a power of 10 as the base which fits in the range of your integer.
For example if your number be 1234567890987654321 and you want to store it in linked list choosing the base to be 10^8 then your representation should look like:
87654321-> 4567890 -> 123(little endian)
Here's my hacky attempt in Java that runs in about O(max(len(a),len(b))). I've provided a complete sample with a very simple singly linked list implementation. It's quite late here so the code is not as nice as I'd like - sorry!
This code assumes:
That the length of the lists is known
Singly linked list
Dealing with integer data
It uses recursion to propagate the sums and carry for each digit, and sums left to right. The lists are never reversed - sums are performed left to right, and carry propagates up the recursive stack. It could be unrolled in an iterative solution, but I won't worry about that.
public class LinkedListSum {
static class LLNode {
int value;
LLNode next;
public LLNode(int value){
this.value = value;
}
public int length(){
LLNode node = this;
int count = 0;
do {
count++;
} while((node = node.next) != null);
return count;
}
public List<Integer> toList(){
List<Integer> res = new ArrayList<Integer>();
LLNode node = this;
while(node != null){
res.add(node.value);
node = node.next;
}
return res;
}
}
public static void main(String[] argc){
LLNode list_a = fromArray(new int[]{4,7,4,7});
LLNode list_b = fromArray(new int[]{5,3,7,4,7,4});
System.out.println("Sum: " + sum(list_a, list_b).toList());
}
private static LLNode fromArray(int[] arr){
LLNode res = new LLNode(0);
LLNode current = res;
for(int i = 0; i < arr.length; i++){
LLNode node = new LLNode(arr[i]);
current.next = node;
current = node;
}
return res.next;
}
private static LLNode sum(LLNode list_1, LLNode list_2){
LLNode longer;
LLNode shorter;
if(list_1.length() >= list_2.length()){
longer = list_1;
shorter = list_2;
} else {
longer = list_2;
shorter = list_1;
}
// Pad short to same length as long
int diff = longer.length() - shorter.length();
for(int i = 0; i < diff; i++){
LLNode temp = new LLNode(0);
temp.next = shorter;
shorter = temp;
}
System.out.println("Longer: " + longer.toList());
System.out.println("Shorter: " + shorter.toList());
return sum_same_length(new LLNode(0), null, longer, shorter);
}
private static LLNode sum_same_length(LLNode current, LLNode previous, LLNode longerList, LLNode shorterList){
LLNode result = current;
if(longerList == null){
previous.next = null;
return result;
}
int sum = longerList.value + shorterList.value;
int first_value = sum % 10;
int first_carry = sum / 10;
current.value = first_value;
// Propagate the carry backwards - increase next multiple of 10 if necessary
LLNode root = propagateCarry(current,previous,first_carry);
current.next = new LLNode(0);
sum_same_length(current.next, current, longerList.next, shorterList.next);
// Propagate the carry backwards - increase next multiple of 10 if necessary:
// The current value could have been increased during the recursive call
int second_value = current.value % 10;
int second_carry = current.value / 10;
current.value = second_value;
root = propagateCarry(current,previous,second_carry);
if(root != null) result = root;
return result;
}
// Returns the new root of the linked list if one had to be added (due to carry)
private static LLNode propagateCarry(LLNode current, LLNode previous, int carry){
LLNode result = null;
if(carry != 0){
if(previous != null){
previous.value += carry;
} else {
LLNode first = new LLNode(carry);
first.next = current;
result = first;
}
}
return result;
}
}
Here is a pseudo code.
list *add (list *l1, list *l2)
{
node *l3, l3_old;
while (l1 != NULL)
{
stack1.push (l1);
l1 = l1->next;
}
while (l2 != NULL)
{
stack2.push (l2);
l2 = l2->next;
}
l3_old = NULL;
while (!stack1.isempty () && !stack2.isempty ()) // at least one stack is not empty
{
l3 = get_new_node ();
l1 = stack1.pop ();
l2 = stack2.pop ();
l3->val = l1->val + l2->val;
if (l3_old != NULL)
{
l3->val = l3->val + (int)l3_old/10;
l3_old->val %= 10;
}
l3->next = l3_old;
l3_old = l3;
}
while (!stack1.isempty ())
{
l1 = stack1.pop ();
l3 = get_new_node ();
l3->val = l1->val + (int)l3_old->val/10;
l3_old->val %= 10;
l3->next = l3_old;
l3_old = l3;
}
while (!stack2.isempty ())
{
l2 = stack2.pop ();
l3 = get_new_node ();
l3->val = l2->val + (int)l3_old->val/10;
l3_old->val %= 10;
l3->next = l3_old;
l3_old = l3;
}
return l3;
}
Here is my attempt, using the two linked lists and returning the sum as a new list using recursion.
public class SumList {
int[] a1= {7,3,2,8};
int[] a2= {4,6,8,4};
LinkedList l1= new LinkedList(a1);
LinkedList l2= new LinkedList(a2);
Node num1= l1.createList();
Node num2= l2.createList();
Node result;
public static void main(String[] args) {
SumList sl= new SumList();
int c= sl.sum(sl.num1, sl.num2);
if(c>0) {
Node temp= new Node(c);
temp.next= sl.result;
sl.result= temp;
}
while(sl.result != null){
System.out.print(sl.result.data);
sl.result= sl.result.next;
}
}
int sum(Node n1, Node n2) {
if(n1==null || n2==null)
return 0;
int a1= this.getSize(n1);
int a2= this.getSize(n2);
int carry, s= 0;
if(a1>a2) {
carry= sum(n1.next, n2);
s= n1.data+carry;
}
else if(a2>a1) {
carry= sum(n1, n2.next);
s= n2.data+carry;
}
else {
carry= sum(n1.next, n2.next);
s= n1.data+n2.data+carry;
}
carry= s/10;
s=s%10;
Node temp= new Node(s);
temp.next= result;
result= temp;
return carry;
}
int getSize(Node n) {
int count =0;
while(n!=null) {
n=n.next;
count++;
}
return count;
}
}
// A recursive program to add two linked lists
#include <stdio.h>
#include <stdlib.h>
// A linked List Node
struct node
{
int data;
struct node* next;
};
typedef struct node node;
/* A utility function to insert a node at the beginning of linked list */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* A utility function to print linked list */
void printList(struct node *node)
{
while (node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
printf("\n");
}
// A utility function to swap two pointers
void swapPointer( node** a, node** b )
{
node* t = *a;
*a = *b;
*b = t;
}
/* A utility function to get size of linked list */
int getSize(struct node *node)
{
int size = 0;
while (node != NULL)
{
node = node->next;
size++;
}
return size;
}
// Adds two linked lists of same size represented by head1 and head2 and returns
// head of the resultant linked list. Carry is propagated while returning from
// the recursion
node* addSameSize(node* head1, node* head2, int* carry)
{
// Since the function assumes linked lists are of same size,
// check any of the two head pointers
if (head1 == NULL)
return NULL;
int sum;
// Allocate memory for sum node of current two nodes
node* result = (node *)malloc(sizeof(node));
// Recursively add remaining nodes and get the carry
result->next = addSameSize(head1->next, head2->next, carry);
// add digits of current nodes and propagated carry
sum = head1->data + head2->data + *carry;
*carry = sum / 10;
sum = sum % 10;
// Assigne the sum to current node of resultant list
result->data = sum;
return result;
}
// This function is called after the smaller list is added to the bigger
// lists's sublist of same size. Once the right sublist is added, the carry
// must be added toe left side of larger list to get the final result.
void addCarryToRemaining(node* head1, node* cur, int* carry, node** result)
{
int sum;
// If diff. number of nodes are not traversed, add carry
if (head1 != cur)
{
addCarryToRemaining(head1->next, cur, carry, result);
sum = head1->data + *carry;
*carry = sum/10;
sum %= 10;
// add this node to the front of the result
push(result, sum);
}
}
// The main function that adds two linked lists represented by head1 and head2.
// The sum of two lists is stored in a list referred by result
void addList(node* head1, node* head2, node** result)
{
node *cur;
// first list is empty
if (head1 == NULL)
{
*result = head2;
return;
}
// second list is empty
else if (head2 == NULL)
{
*result = head1;
return;
}
int size1 = getSize(head1);
int size2 = getSize(head2) ;
int carry = 0;
// Add same size lists
if (size1 == size2)
*result = addSameSize(head1, head2, &carry);
else
{
int diff = abs(size1 - size2);
// First list should always be larger than second list.
// If not, swap pointers
if (size1 < size2)
swapPointer(&head1, &head2);
// move diff. number of nodes in first list
for (cur = head1; diff--; cur = cur->next);
// get addition of same size lists
*result = addSameSize(cur, head2, &carry);
// get addition of remaining first list and carry
addCarryToRemaining(head1, cur, &carry, result);
}
// if some carry is still there, add a new node to the fron of
// the result list. e.g. 999 and 87
if (carry)
push(result, carry);
}
// Driver program to test above functions
int main()
{
node *head1 = NULL, *head2 = NULL, *result = NULL;
int arr1[] = {9, 9, 9};
int arr2[] = {1, 8};
int size1 = sizeof(arr1) / sizeof(arr1[0]);
int size2 = sizeof(arr2) / sizeof(arr2[0]);
// Create first list as 9->9->9
int i;
for (i = size1-1; i >= 0; --i)
push(&head1, arr1[i]);
// Create second list as 1->8
for (i = size2-1; i >= 0; --i)
push(&head2, arr2[i]);
addList(head1, head2, &result);
printList(result);
return 0;
}
1.First traverse the two lists and find the lengths of the two lists(Let m,n be the lengths).
2.Traverse n-m nodes in the longer list and set 'prt1' to the current node and 'ptr2' to beginning of the other list.
3.Now call the following recursive function with flag set to zero:
void add(node* ptr1,node* ptr2){
if(ptr1==NULL)
return;
add(ptr1->next,ptr2->next);
insertAtBegin(ptr1->data+ptr2->data+flag);
flag=(ptr1->data+ptr2->data)%10;
}
4.Now you need to add the remaining n-m nodes at the beginning of your target list, you can do it directly using a loop. Please note that for the last element in the loop you need to add the flag returned by the add() function as there might be a carry.
If your question is without using recursion:
1.Repeat the first two steps, then create your target list initalising every elements with '0'(make sure that the length of the list is accurate).
2.Traverse the two lists along with your target list(a step behind).If you find sum of two nodes greater than 10, make the value in the target list as '1'.
3.With the above step you took care of the carry. Now in one more pass just add the two nodes modulo 10 and add this value in the corresponding node of the target list.
without using stack .....
simply store the content of link list in array and perform addition and and then again put addition into link list
code :
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
int value;
struct node *next;
}node;
int main()
{
printf("\nEnter the number 1 : ");
int ch;
node *p=NULL;
node *k=NULL;
printf("\nEnter the number of digit : ");
scanf("%d",&ch);
int i=0;
while(ch!=i)
{
i++;
node *q=NULL;
int a=0;
q=(node *)malloc(sizeof(node));
printf("\nEnter value : ");
scanf("%d",&a);
q->value=a;
if(p==NULL)
{
q->next=NULL;
p=q;
k=p;
}
else
{
q->next=NULL;
p->next=q;
p=q;
}
}
printf("\nEnter the number 2 : ");
int ch1;
node *p1=NULL;
node *k1=NULL;
int i1=0;
printf("\nEnter the number of digit : ");
scanf("%d",&ch1);
while(ch1!=i1)
{
i1++;
node *q1=NULL;
int a1=0;
q1=(node *)malloc(sizeof(node));
printf("\nEnter value : ");
scanf("%d",&a1);
q1->value=a1;
if(p1==NULL)
{
q1->next=NULL;
p1=q1;
k1=p1;
}
else
{
q1->next=NULL;
p1->next=q1;
p1=q1;
}
}
printf("\n\t");
int arr1[100];
int arr1_ptr=0;
while(k != NULL )
{
printf("%d\t",k->value);
arr1[arr1_ptr++]=k->value;
k=k->next;
}
printf("\n\t");
int arr2[100];
int arr2_ptr=0;
while(k1 != NULL )
{
printf("%d\t",k1->value);
arr2[arr2_ptr++]=k1->value;
k1=k1->next;
}
//addition logic ...
int result[100]={0};
int result_ptr=0;
int loop_ptr=0;
int carry=0;
arr1_ptr--;
arr2_ptr--;
if(arr1_ptr>arr2_ptr)
loop_ptr=arr1_ptr+1;
else
loop_ptr=arr2_ptr+1;
for(int i = loop_ptr ; i >= 0;i--)
{
if(arr1_ptr >= 0 && arr2_ptr >= 0)
{
if( (arr1[arr1_ptr] + arr2[arr2_ptr] + carry ) > 9 )
{
result[i]=((arr1[arr1_ptr] + arr2[arr2_ptr]+carry) % 10 );
carry = ((arr1[arr1_ptr--] + arr2[arr2_ptr--]+carry ) / 10 ) ;
}
else
{
result[i]=(arr1[arr1_ptr--] + arr2[arr2_ptr--] + carry );
carry = 0 ;
}
}
else if( !(arr1_ptr < 0 ) || !( arr2_ptr < 0 ) )
{
if( arr1_ptr < 0)
result[i]=arr2[arr2_ptr--]+carry;
else
result[i]=arr1[arr1_ptr--]+carry;
}
else
result[i]=carry;
}
/*printf("\n");
for(int i=0;i<loop_ptr+1;i++)
printf("%d\t",result[i]);
*/
node *k2=NULL,*p2=NULL;
for(int i=0;i<loop_ptr+1;i++)
{
node *q2=NULL;
q2=(node *)malloc(sizeof(node));
q2->value=result[i];
if(p2==NULL)
{
q2->next=NULL;
p2=q2;
k2=p2;
}
else
{
q2->next=NULL;
p2->next=q2;
p2=q2;
}
}
printf("\n");
while(k2 != NULL )
{
printf("%d\t",k2->value);
k2=k2->next;
}
return 0;
}
We can add them by using recursion. Assume the question is defined as follows: we have lists l1 and l2 and we want to add them by storing the result in l1. For simplicity assume that both lists have the same length (the code can be easily modified to work for different lengths). Here is my working Java solution:
private static ListNode add(ListNode l1, ListNode l2){
if(l1 == null)
return l2;
if(l2 == null)
return l1;
int[] carry = new int[1];
add(l1, l2, carry);
if(carry[0] != 0){
ListNode newHead = new ListNode(carry[0]);
newHead.next = l1;
return newHead;
}
return l1;
}
private static void add(ListNode l1, ListNode l2, int[] carry) {
if(l1.next == null && l2.next == null){
carry[0] = l1.val + l2.val;
l1.val = carry[0]%10;
carry[0] /= 10;
return;
}
add(l1.next, l2.next, carry);
carry[0] += l1.val + l2.val;
l1.val = carry[0]%10;
carry[0] /= 10;
}
Input : List a , List b
Output : List c
Most approaches here require extra space for List a and List b. This can be removed.
Reverse List a and List b so that they are represented in the reverse order (i.e., tail as head and all the links reversed) with constant space of O(1).
Then add the lists efficiently by traversing through both of them simultaneously and maintaining a carry.
Reverse List a and List b if required
Try this
/* No Recursion, No Reversal - Java */
import java.util.*;
class LinkedListAddMSB
{
static LinkedList<Integer> addList(LinkedList<Integer> num1, LinkedList<Integer> num2)
{
LinkedList<Integer> res = new LinkedList<Integer>();
LinkedList<Integer> shorter = new LinkedList<Integer>();
LinkedList<Integer> longer = new LinkedList<Integer>();
int carry = 0;
int maxlen,minlen;
if(num1.size() >= num2.size())
{
maxlen = num1.size();
minlen = num2.size();
shorter = num2;
longer = num1;
}
else
{
maxlen = num2.size();
minlen = num1.size();
shorter = num1;
longer = num2;
}
//Pad shorter list to same length by adding preceeding 0
int diff = maxlen - minlen;
for(int i=0; i<diff; i++)
{
shorter.addFirst(0);
}
for(int i=maxlen-1; i>=0; i--)
{
int temp1 = longer.get(i);
int temp2 = shorter.get(i);
int temp3 = temp1 + temp2 + carry;
carry = 0;
if(temp3 >= 10)
{
carry = (temp3/10)%10;
temp3 = temp3%10;
}
res.addFirst(temp3);
}
if(carry > 0)
res.addFirst(carry);
return res;
}
public static void main(String args[])
{
LinkedList<Integer> num1 = new LinkedList<Integer>();
LinkedList<Integer> num2 = new LinkedList<Integer>();
LinkedList<Integer> res = new LinkedList<Integer>();
//64957
num1.add(6);
num1.add(4);
num1.add(9);
num1.add(5);
num1.add(7);
System.out.println("First Number: " + num1);
//48
num2.add(4);
num2.add(8);
System.out.println("First Number: " + num2);
res = addList(num1,num2);
System.out.println("Result: " + res);
}
}
/* this baby does not reverse the list
** , it does use recursion, and it uses a scratch array */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct list {
struct list *next;
unsigned value;
};
unsigned recurse( char target[], struct list *lp);
struct list * grab ( char buff[], size_t len);
unsigned recurse( char target[], struct list *lp)
{
unsigned pos;
if (!lp) return 0;
pos = recurse (target, lp->next);
/* We should do a bounds check target[] here */
target[pos] += lp->value;
if (target[pos] >= 10) {
target[pos+1] += target[pos] / 10;
target[pos] %= 10;
}
return 1+pos;
}
struct list * grab ( char *buff, size_t len)
{
size_t idx;
struct list *ret, **hnd;
/* Skip prefix of all zeros. */
for (idx=len; idx--; ) {
if (buff [idx] ) break;
}
if (idx >= len) return NULL;
/* Build the result chain. Buffer has it's LSB at index=0,
** but we just found the MSB at index=idx.
*/
ret = NULL; hnd = &ret;
do {
*hnd = malloc (sizeof **hnd);
(*hnd)->value = buff[idx];
(*hnd)->next = NULL;
hnd = &(*hnd)->next;
} while (idx--);
return ret;
}
int main (void)
{
char array[10];
struct list a[] = { {NULL, 2} , {NULL, 1} , {NULL, 7} };
struct list b[] = { {NULL, 3} , {NULL, 4} };
struct list *result;
a[0].next = &a[1]; a[1].next = &a[2];
b[0].next = &b[1];
memset(array, 0 , sizeof array );
(void) recurse ( array, a);
(void) recurse ( array, b);
result = grab ( array, sizeof array );
for ( ; result; result = result->next ) {
printf( "-> %u" , result->value );
}
printf( "\n" );
return 0;
}
Final version (no list reversal, no recursion):
#include <stdio.h>
#include <stdlib.h>
struct list {
struct list *nxt;
unsigned val;
};
struct list *sumlist(struct list *l, struct list *r);
int difflen(struct list *l, struct list *r);
struct list *sumlist(struct list *l, struct list *r)
{
int carry,diff;
struct list *result= NULL, **pp = &result;
/* If the lists have different lengths,
** the sum will start with the prefix of the longest list
*/
for (diff = difflen(l, r); diff; diff += (diff > 0) ? -1 : 1) {
*pp = malloc (sizeof **pp) ;
(*pp)->nxt = NULL;
if (diff > 0) { (*pp)->val = l->val; l= l->nxt; }
else { (*pp)->val = r->val; r= r->nxt; }
pp = &(*pp)->nxt ;
}
/* Do the summing.
** whenever the sum is ten or larger we increment a carry counter
*/
for (carry=0; l && r; l=l->nxt, r=r->nxt) {
*pp = malloc (sizeof **pp) ;
(*pp)->nxt = NULL;
(*pp)->val = l->val + r->val;
if ((*pp)->val > 9) carry++;
pp = &(*pp)->nxt ;
}
/* While there are any carries, we will need to propagate them.
** Because we cannot reverse the list (or walk it backward),
** this has to be done iteratively.
** Special case: if the first digit needs a carry,
** we have to insert a node in front of it
*/
for (diff =0 ;carry; carry = diff) {
struct list *tmp;
if (result && result->val > 9) {
tmp = malloc(sizeof *tmp);
tmp->nxt = result;
tmp->val = 0;
result = tmp;
}
diff=0;
for (tmp=result; tmp ; tmp= tmp->nxt) {
if (tmp->nxt && tmp->nxt->val > 9) {
tmp->val += tmp->nxt->val/10;
tmp->nxt->val %= 10; }
if (tmp->val > 9) diff++;
}
}
return result;
}
int difflen(struct list *l, struct list *r)
{
int diff;
for (diff=0; l || r; l = (l)?l->nxt:l, r = (r)?r->nxt:r ) {
if (l && r) continue;
if (l) diff++; else diff--;
}
return diff;
}
int main (void)
{
struct list one[] = { {one+1, 2} , {one+2, 6} , {NULL, 7} };
struct list two[] = { {two+1, 7} , {two+2, 3} , {NULL, 4} };
struct list *result;
result = sumlist(one, two);
for ( ; result; result = result->nxt ) {
printf( "-> %u" , result->val );
}
printf( ";\n" );
return 0;
}
In java i will do it this way
public class LLSum {
public static void main(String[] args) {
LinkedList<Integer> ll1 = new LinkedList<Integer>();
LinkedList<Integer> ll2 = new LinkedList<Integer>();
ll1.add(7);
ll1.add(5);
ll1.add(9);
ll1.add(4);
ll1.add(6);
ll2.add(8);
ll2.add(4);
System.out.println(addLists(ll1,ll2));
}
public static LinkedList<Integer> addLists(LinkedList<Integer> ll1, LinkedList<Integer> ll2){
LinkedList<Integer> finalList = null;
int num1 = makeNum(ll1);
int num2 = makeNum(ll2);
finalList = makeList(num1+num2);
return finalList;
}
private static LinkedList<Integer> makeList(int num) {
LinkedList<Integer> newList = new LinkedList<Integer>();
int temp=1;
while(num!=0){
temp = num%10;
newList.add(temp);
num = num/10;
}
return newList;
}
private static int makeNum(LinkedList<Integer> ll) {
int finalNum = 0;
for(int i=0;i<ll.size();i++){
finalNum += ll.get(i) * Math.pow(10,i);
}
return finalNum;
}
}
Here is my first try:
public class addTwo {
public static void main(String args[]){
LinkedListNode m =new LinkedListNode(3);
LinkedListNode n = new LinkedListNode(5);
m.appendNew(1);
m.appendNew(5);
m.appendNew(5);
n.appendNew(9);
n.appendNew(2);
n.appendNew(5);
n.appendNew(9);
n.appendNew(9 );
m.print();
n.print();
LinkedListNode add=addTwo(m,n);
add.print();
}
static LinkedListNode addTwo(LinkedListNode m,LinkedListNode n){
LinkedListNode result;
boolean flag =false;
int num;
num=m.data+n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result = new LinkedListNode(num%10);
while(m.link!=null && n.link!=null){
m=m.link;
n=n.link;
num=m.data+n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
if(m.link==null && n.link==null){
if(flag)
result.appendNew(1);
flag=false;
}else if(m.link!=null){
while(m.link !=null){
m=m.link;
num=m.data;
num=m.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
}else{
while(n.link !=null){
n=n.link;
num=n.data;
num=n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
}
if(flag){
result.appendNew(1);
}
return result;
}
class LinkedListNode {
public int data;
public LinkedListNode link;
public LinkedListNode(){System.out.println(this+":"+this.link+":"+this.data);}
public LinkedListNode(int data){
this.data=data;
}
void appendNew(int data){
if(this==null){
System.out.println("this is null");
LinkedListNode newNode = new LinkedListNode(data);
}
LinkedListNode newNode = new LinkedListNode(data);
LinkedListNode prev =this;
while(prev.link!=null){
prev = prev.link;
}
prev.link=newNode;
}
void print(){
LinkedListNode n=this;
while(n.link!=null){
System.out.print(n.data +"->");
n = n.link;
}
System.out.println(n.data);
}
}
result is:
3->1->5->5
5->9->2->5->9->9
8->0->8->0->0->0->1
My recursive Java implementation:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
return addTwoNumbers(l1, l2, 0);
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2, int carryOver) {
int result;
ListNode next = null;
if (l1 == null && l2 == null) {
if (carryOver > 0) {
return new ListNode(carryOver);
} else {
return null;
}
} else if (l1 == null && l2 != null) {
result = l2.val + carryOver;
next = addTwoNumbers(null, l2.next, result / 10);
} else if (l1 != null && l2 == null){
result = l1.val + carryOver;
next = addTwoNumbers(l1.next, null, result / 10);
} else {
result = l1.val + l2.val + carryOver;
next = addTwoNumbers(l1.next, l2.next, result / 10);
}
ListNode node = new ListNode(result % 10);
node.next = next;
return node;
}
}
Hope that helps.
/* spoiler: just plain recursion will do */
#include <stdio.h>
struct list {
struct list *next;
unsigned value;
};
struct list a[] = { {NULL, 2} , {NULL, 1} , {NULL, 7} };
struct list b[] = { {NULL, 3} , {NULL, 4} };
unsigned recurse( unsigned * target, struct list *lp);
unsigned recurse( unsigned * target, struct list *lp)
{
unsigned fact;
if (!lp) return 1;
fact = recurse (target, lp->next);
*target += fact * lp->value;
return 10*fact;
}
int main (void)
{
unsigned result=0;
/* set up the links */
a[0].next = &a[1];
a[1].next = &a[2];
b[0].next = &b[1];
(void) recurse ( &result, a);
(void) recurse ( &result, b);
printf( "Result = %u\n" , result );
return 0;
}

Resources