Interview Question: Merge two sorted singly linked lists without creating new nodes - algorithm

This is a programming question asked during a written test for an interview.
"You have two singly linked lists that are already sorted, you have to merge them and return a the head of the new list without creating any new extra nodes. The returned list should be sorted as well"
The method signature is:
Node MergeLists(Node list1, Node list2);
Node class is below:
class Node{
int data;
Node next;
}
I tried many solutions but not creating an extra node screws things. Please help.
Here is the accompanying blog entry http://techieme.in/merging-two-sorted-singly-linked-list/

Node MergeLists(Node list1, Node list2) {
if (list1 == null) return list2;
if (list2 == null) return list1;
if (list1.data < list2.data) {
list1.next = MergeLists(list1.next, list2);
return list1;
} else {
list2.next = MergeLists(list2.next, list1);
return list2;
}
}

Recursion should not be needed to avoid allocating a new node:
Node MergeLists(Node list1, Node list2) {
if (list1 == null) return list2;
if (list2 == null) return list1;
Node head;
if (list1.data < list2.data) {
head = list1;
} else {
head = list2;
list2 = list1;
list1 = head;
}
while(list1.next != null) {
if (list1.next.data > list2.data) {
Node tmp = list1.next;
list1.next = list2;
list2 = tmp;
}
list1 = list1.next;
}
list1.next = list2;
return head;
}

Node MergeLists(Node node1, Node node2)
{
if(node1 == null)
return node2;
else (node2 == null)
return node1;
Node head;
if(node1.data < node2.data)
{
head = node1;
node1 = node1.next;
else
{
head = node2;
node2 = node2.next;
}
Node current = head;
while((node1 != null) ||( node2 != null))
{
if (node1 == null) {
current.next = node2;
return head;
}
else if (node2 == null) {
current.next = node1;
return head;
}
if (node1.data < node2.data)
{
current.next = node1;
current = current.next;
node1 = node1.next;
}
else
{
current.next = node2;
current = current.next;
node2 = node2.next;
}
}
current.next = NULL // needed to complete the tail of the merged list
return head;
}

Look ma, no recursion!
struct llist * llist_merge(struct llist *one, struct llist *two, int (*cmp)(struct llist *l, struct llist *r) )
{
struct llist *result, **tail;
for (result=NULL, tail = &result; one && two; tail = &(*tail)->next ) {
if (cmp(one,two) <=0) { *tail = one; one=one->next; }
else { *tail = two; two=two->next; }
}
*tail = one ? one: two;
return result;
}

Here is the algorithm on how to merge two sorted linked lists A and B:
while A not empty or B not empty:
if first element of A < first element of B:
remove first element from A
insert element into C
end if
else:
remove first element from B
insert element into C
end while
Here C will be the output list.

Iteration can be done as below. Complexity = O(n)
public static LLNode mergeSortedListIteration(LLNode nodeA, LLNode nodeB) {
LLNode mergedNode ;
LLNode tempNode ;
if (nodeA == null) {
return nodeB;
}
if (nodeB == null) {
return nodeA;
}
if ( nodeA.getData() < nodeB.getData())
{
mergedNode = nodeA;
nodeA = nodeA.getNext();
}
else
{
mergedNode = nodeB;
nodeB = nodeB.getNext();
}
tempNode = mergedNode;
while (nodeA != null && nodeB != null)
{
if ( nodeA.getData() < nodeB.getData())
{
mergedNode.setNext(nodeA);
nodeA = nodeA.getNext();
}
else
{
mergedNode.setNext(nodeB);
nodeB = nodeB.getNext();
}
mergedNode = mergedNode.getNext();
}
if (nodeA != null)
{
mergedNode.setNext(nodeA);
}
if (nodeB != null)
{
mergedNode.setNext(nodeB);
}
return tempNode;
}

Node mergeList(Node h1, Node h2) {
if (h1 == null) return h2;
if (h2 == null) return h1;
Node head;
if (h1.data < h2.data) {
head = h1;
} else {
head = h2;
h2 = h1;
h1 = head;
}
while (h1.next != null && h2 != null) {
if (h1.next.data < h2.data) {
h1 = h1.next;
} else {
Node afterh2 = h2.next;
Node afterh1 = h1.next;
h1.next = h2;
h2.next = afterh1;
if (h2.next != null) {
h2 = afterh2;
}
}
}
return head;
}

This could be done without creating the extra node, with just an another Node reference passing to the parameters (Node temp).
private static Node mergeTwoLists(Node nodeList1, Node nodeList2, Node temp) {
if(nodeList1 == null) return nodeList2;
if(nodeList2 == null) return nodeList1;
if(nodeList1.data <= nodeList2.data){
temp = nodeList1;
temp.next = mergeTwoLists(nodeList1.next, nodeList2, temp);
}
else{
temp = nodeList2;
temp.next = mergeTwoLists(nodeList1, nodeList2.next, temp);
}
return temp;
}

I would like to share how i thought the solution... i saw the solution that involves recursion and they are pretty amazing, is the outcome of well functional and modular thinking. I really appreciate the sharing.
I would like to add that recursion won't work for big lits, the stack calls will overflow; so i decided to try the iterative approach... and this is what i get.
The code is pretty self explanatory, i added some inline comments to try to assure this.
If you don't get it, please notify me and i will improve the readability (perhaps i am having a misleading interpretation of my own code).
import java.util.Random;
public class Solution {
public static class Node<T extends Comparable<? super T>> implements Comparable<Node<T>> {
T data;
Node next;
#Override
public int compareTo(Node<T> otherNode) {
return data.compareTo(otherNode.data);
}
#Override
public String toString() {
return ((data != null) ? data.toString() + ((next != null) ? "," + next.toString() : "") : "null");
}
}
public static Node merge(Node firstLeft, Node firstRight) {
combine(firstLeft, firstRight);
return Comparision.perform(firstLeft, firstRight).min;
}
private static void combine(Node leftNode, Node rightNode) {
while (leftNode != null && rightNode != null) {
// get comparision data about "current pair of nodes being analized".
Comparision comparision = Comparision.perform(leftNode, rightNode);
// stores references to the next nodes
Node nextLeft = leftNode.next;
Node nextRight = rightNode.next;
// set the "next node" of the "minor node" between the "current pair of nodes being analized"...
// ...to be equals the minor node between the "major node" and "the next one of the minor node" of the former comparision.
comparision.min.next = Comparision.perform(comparision.max, comparision.min.next).min;
if (comparision.min == leftNode) {
leftNode = nextLeft;
} else {
rightNode = nextRight;
}
}
}
/** Stores references to two nodes viewed as one minimum and one maximum. The static factory method populates properly the instance being build */
private static class Comparision {
private final Node min;
private final Node max;
private Comparision(Node min, Node max) {
this.min = min;
this.max = max;
}
private static Comparision perform(Node a, Node b) {
Node min, max;
if (a != null && b != null) {
int comparision = a.compareTo(b);
if (comparision <= 0) {
min = a;
max = b;
} else {
min = b;
max = a;
}
} else {
max = null;
min = (a != null) ? a : b;
}
return new Comparision(min, max);
}
}
// Test example....
public static void main(String args[]) {
Node firstLeft = buildList(20);
Node firstRight = buildList(40);
Node firstBoth = merge(firstLeft, firstRight);
System.out.println(firstBoth);
}
// someone need to write something like this i guess...
public static Node buildList(int size) {
Random r = new Random();
Node<Integer> first = new Node<>();
first.data = 0;
first.next = null;
Node<Integer> current = first;
Integer last = first.data;
for (int i = 1; i < size; i++) {
Node<Integer> node = new Node<>();
node.data = last + r.nextInt(5);
last = node.data;
node.next = null;
current.next = node;
current = node;
}
return first;
}
}

A simple iterative solution.
Node* MergeLists(Node* A, Node* B)
{
//handling the corner cases
//if both lists are empty
if(!A && !B)
{
cout << "List is empty" << endl;
return 0;
}
//either of list is empty
else if(!A) return B;
else if(!B) return A;
else
{
Node* head = NULL;//this will be the head of the newList
Node* previous = NULL;//this will act as the
/* In this algorithm we will keep the
previous pointer that will point to the last node of the output list.
And, as given we have A & B as pointer to the given lists.
The algorithm will keep on going untill either one of the list become empty.
Inside of the while loop, it will divide the algorithm in two parts:
- First, if the head of the output list is not obtained yet
- Second, if head is already there then we will just compare the values and keep appending to the 'previous' pointer.
When one of the list become empty we will append the other 'left over' list to the output list.
*/
while(A && B)
{
if(!head)
{
if(A->data <= B->data)
{
head = A;//setting head of the output list to A
previous = A; //initializing previous
A = A->next;
}
else
{
head = B;//setting head of the output list to B
previous = B;//initializing previous
B = B->next;
}
}
else//when head is already set
{
if(A->data <= B->data)
{
if(previous->next != A)
previous->next = A;
A = A->next;//Moved A forward but keeping B at the same position
}
else
{
if(previous->next != B)
previous->next = B;
B = B->next; //Moved B forward but keeping A at the same position
}
previous = previous->next;//Moving the Output list pointer forward
}
}
//at the end either one of the list would finish
//and we have to append the other list to the output list
if(!A)
previous->next = B;
if(!B)
previous->next = A;
return head; //returning the head of the output list
}
}

I show below an iterative solution. A recursive solution would be more compact, but since we don't know the length of the lists, recursion runs the risk of stack overflow.
The basic idea is similar to the merge step in merge sort; we keep a pointer corresponding to each input list; at each iteration, we advance the pointer corresponding to the smaller element. However, there's one crucial difference where most people get tripped. In merge sort, since we use a result array, the next position to insert is always the index of the result array. For a linked list, we need to keep a pointer to the last element of the sorted list. The pointer may jump around from one input list to another depending on which one has the smaller element for the current iteration.
With that, the following code should be self-explanatory.
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode first = l1;
ListNode second = l2;
ListNode head = null;
ListNode last = null;
while (first != null && second != null) {
if (first.val < second.val) {
if (last != null) {
last.next = first;
}
last = first;
first = first.next;
} else {
if (last != null) {
last.next = second;
}
last = second;
second = second.next;
}
if (head == null) {
head = last;
}
}
if (first == null) {
last.next = second;
}
if (second == null) {
last.next = first;
}
return head;
}

Simple code in javascript to merge two linked list inplace.
function mergeLists(l1, l2) {
let head = new ListNode(0); //dummy
let curr = head;
while(l1 && l2) {
if(l2.val >= l1.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2=l2.next
}
curr = curr.next;
}
if(!l1){
curr.next=l2;
}
if(!l2){
curr.next=l1;
}
return head.next;
}

First of all understand the mean of "without creating any new extra nodes", As I understand it does not mean that I can not have pointer(s) which points to an existing node(s).
You can not achieve it without talking pointers to existing nodes, even if you use recursion to achieve the same, system will create pointers for you as call stacks. It is just like telling system to add pointers which you have avoided in your code.
Simple function to achieve the same with taking extra pointers:
typedef struct _LLNode{
int value;
struct _LLNode* next;
}LLNode;
LLNode* CombineSortedLists(LLNode* a,LLNode* b){
if(NULL == a){
return b;
}
if(NULL == b){
return a;
}
LLNode* root = NULL;
if(a->value < b->value){
root = a;
a = a->next;
}
else{
root = b;
b = b->next;
}
LLNode* curr = root;
while(1){
if(a->value < b->value){
curr->next = a;
curr = a;
a=a->next;
if(NULL == a){
curr->next = b;
break;
}
}
else{
curr->next = b;
curr = b;
b=b->next;
if(NULL == b){
curr->next = a;
break;
}
}
}
return root;
}

Node * merge_sort(Node *a, Node *b){
Node *result = NULL;
if(a == NULL)
return b;
else if(b == NULL)
return a;
/* For the first node, we would set the result to either a or b */
if(a->data <= b->data){
result = a;
/* Result's next will point to smaller one in lists
starting at a->next and b */
result->next = merge_sort(a->next,b);
}
else {
result = b;
/*Result's next will point to smaller one in lists
starting at a and b->next */
result->next = merge_sort(a,b->next);
}
return result;
}
Please refer to my blog post for http://www.algorithmsandme.com/2013/10/linked-list-merge-two-sorted-linked.html

Node MergeLists(Node list1, Node list2) {
//if list is null return other list
if(list1 == null)
{
return list2;
}
else if(list2 == null)
{
return list1;
}
else
{
Node head;
//Take head pointer to the node which has smaller first data node
if(list1.data < list2.data)
{
head = list1;
list1 = list1.next;
}
else
{
head = list2;
list2 = list2.next;
}
Node current = head;
//loop till both list are not pointing to null
while(list1 != null || list2 != null)
{
//if list1 is null, point rest of list2 by current pointer
if(list1 == null){
current.next = list2;
return head;
}
//if list2 is null, point rest of list1 by current pointer
else if(list2 == null){
current.next = list1;
return head;
}
//compare if list1 node data is smaller than list2 node data, list1 node will be
//pointed by current pointer
else if(list1.data < list2.data)
{
current.next = list1;
current = current.next;
list1 = list1.next;
}
else
{
current.next = list2;
current = current.next;
list2 = list2.next;
}
}
return head;
}
}

Here is a complete working example that uses the linked list implemented java.util. You can just copy paste the code below inside a main() method.
LinkedList<Integer> dList1 = new LinkedList<Integer>();
LinkedList<Integer> dList2 = new LinkedList<Integer>();
LinkedList<Integer> dListMerged = new LinkedList<Integer>();
dList1.addLast(1);
dList1.addLast(8);
dList1.addLast(12);
dList1.addLast(15);
dList1.addLast(85);
dList2.addLast(2);
dList2.addLast(3);
dList2.addLast(12);
dList2.addLast(24);
dList2.addLast(85);
dList2.addLast(185);
int i = 0;
int y = 0;
int dList1Size = dList1.size();
int dList2Size = dList2.size();
int list1Item = dList1.get(i);
int list2Item = dList2.get(y);
while (i < dList1Size || y < dList2Size) {
if (i < dList1Size) {
if (list1Item <= list2Item || y >= dList2Size) {
dListMerged.addLast(list1Item);
i++;
if (i < dList1Size) {
list1Item = dList1.get(i);
}
}
}
if (y < dList2Size) {
if (list2Item <= list1Item || i >= dList1Size) {
dListMerged.addLast(list2Item);
y++;
if (y < dList2Size) {
list2Item = dList2.get(y);
}
}
}
}
for(int x:dListMerged)
{
System.out.println(x);
}

Recursive way(variant of Stefan answer)
MergeList(Node nodeA, Node nodeB ){
if(nodeA==null){return nodeB};
if(nodeB==null){return nodeA};
if(nodeB.data<nodeA.data){
Node returnNode = MergeNode(nodeA,nodeB.next);
nodeB.next = returnNode;
retturn nodeB;
}else{
Node returnNode = MergeNode(nodeA.next,nodeB);
nodeA.next=returnNode;
return nodeA;
}
Consider below linked list to visualize this
2>4 list A
1>3 list B
Almost same answer(non recursive) as Stefan but with little more comments/meaningful variable name. Also covered double linked list in comments if someone is interested
Consider the example
5->10->15>21 // List1
2->3->6->20 //List2
Node MergeLists(List list1, List list2) {
if (list1 == null) return list2;
if (list2 == null) return list1;
if(list1.head.data>list2.head.data){
listB =list2; // loop over this list as its head is smaller
listA =list1;
} else {
listA =list2; // loop over this list
listB =list1;
}
listB.currentNode=listB.head;
listA.currentNode=listA.head;
while(listB.currentNode!=null){
if(listB.currentNode.data<listA.currentNode.data){
Node insertFromNode = listB.currentNode.prev;
Node startingNode = listA.currentNode;
Node temp = inserFromNode.next;
inserFromNode.next = startingNode;
startingNode.next=temp;
startingNode.next.prev= startingNode; // for doubly linked list
startingNode.prev=inserFromNode; // for doubly linked list
listB.currentNode= listB.currentNode.next;
listA.currentNode= listA.currentNode.next;
}
else
{
listB.currentNode= listB.currentNode.next;
}
}

My take on the question is as below:
Pseudocode:
Compare the two heads A and B.
If A <= B, then add A and move the head of A to the next node.
Similarly, if B < A, then add B and move the head of B to the next node B.
If both A and B are NULL then stop and return.
If either of them is NULL, then traverse the non null head till it becomes NULL.
Code:
public Node mergeLists(Node headA, Node headB) {
Node merge = null;
// If we have reached the end, then stop.
while (headA != null || headB != null) {
// if B is null then keep appending A, else check if value of A is lesser or equal than B
if (headB == null || (headA != null && headA.data <= headB.data)) {
// Add the new node, handle addition separately in a new method.
merge = add(merge, headA.data);
// Since A is <= B, Move head of A to next node
headA = headA.next;
// if A is null then keep appending B, else check if value of B is lesser than A
} else if (headA == null || (headB != null && headB.data < headA.data)) {
// Add the new node, handle addition separately in a new method.
merge = add(merge, headB.data);
// Since B is < A, Move head of B to next node
headB = headB.next;
}
}
return merge;
}
public Node add(Node head, int data) {
Node end = new Node(data);
if (head == null) {
return end;
}
Node curr = head;
while (curr.next != null) {
curr = curr.next;
}
curr.next = end;
return head;
}

/* Simple/Elegant Iterative approach in Java*/
private static LinkedList mergeLists(LinkedList list1, LinkedList list2) {
Node head1 = list1.start;
Node head2 = list2.start;
if (list1.size == 0)
return list2;
if (list2.size == 0)
return list1;
LinkedList mergeList = new LinkedList();
while (head1 != null && head2 != null) {
if (head1.getData() < head2.getData()) {
int data = head1.getData();
mergeList.insert(data);
head1 = head1.getNext();
} else {
int data = head2.getData();
mergeList.insert(data);
head2 = head2.getNext();
}
}
while (head1 != null) {
int data = head1.getData();
mergeList.insert(data);
head1 = head1.getNext();
}
while (head2 != null) {
int data = head2.getData();
mergeList.insert(data);
head2 = head2.getNext();
}
return mergeList;
}
/* Build-In singly LinkedList class in Java*/
class LinkedList {
Node start;
int size = 0;
void insert(int data) {
if (start == null)
start = new Node(data);
else {
Node temp = start;
while (temp.getNext() != null) {
temp = temp.getNext();
}
temp.setNext(new Node(data));
}
size++;
}
#Override
public String toString() {
String str = "";
Node temp=start;
while (temp != null) {
str += temp.getData() + "-->";
temp = temp.getNext();
}
return str;
}
}

LLNode *mergeSorted(LLNode *h1, LLNode *h2)
{
LLNode *h3=NULL;
LLNode *h3l;
if(h1==NULL && h2==NULL)
return NULL;
if(h1==NULL)
return h2;
if(h2==NULL)
return h1;
if(h1->data<h2->data)
{
h3=h1;
h1=h1->next;
}
else
{
h3=h2;
h2=h2->next;
}
LLNode *oh=h3;
while(h1!=NULL && h2!=NULL)
{
if(h1->data<h2->data)
{
h3->next=h1;
h3=h3->next;
h1=h1->next;
}
else
{
h3->next=h2;
h3=h3->next;
h2=h2->next;
}
}
if(h1==NULL)
h3->next=h2;
if(h2==NULL)
h3->next=h1;
return oh;
}

// Common code for insert at the end
private void insertEnd(int data) {
Node newNode = new Node(data);
if (head == null) {
newNode.next = head;
head = tail = newNode;
return;
}
Node tempNode = tail;
tempNode.next = newNode;
tail = newNode;
}
private void mergerTwoSortedListInAscOrder(Node tempNode1, Node tempNode2) {
if (tempNode1 == null && tempNode2 == null)
return;
if (tempNode1 == null) {
head3 = tempNode2;
return;
}
if (tempNode2 == null) {
head3 = tempNode1;
return;
}
while (tempNode1 != null && tempNode2 != null) {
if (tempNode1.mData < tempNode2.mData) {
insertEndForHead3(tempNode1.mData);
tempNode1 = tempNode1.next;
} else if (tempNode1.mData > tempNode2.mData) {
insertEndForHead3(tempNode2.mData);
tempNode2 = tempNode2.next;
} else {
insertEndForHead3(tempNode1.mData);
insertEndForHead3(tempNode2.mData);
tempNode1 = tempNode1.next;
tempNode2 = tempNode2.next;
}
}
if (tempNode1 != null) {
while (tempNode1 != null) {
insertEndForHead3(tempNode1.mData);
tempNode1 = tempNode1.next;
}
}
if (tempNode2 != null) {
while (tempNode2 != null) {
insertEndForHead3(tempNode2.mData);
tempNode2 = tempNode2.next;
}
}
}
:)GlbMP

public static Node merge(Node h1, Node h2) {
Node h3 = new Node(0);
Node current = h3;
boolean isH1Left = false;
boolean isH2Left = false;
while (h1 != null || h2 != null) {
if (h1.data <= h2.data) {
current.next = h1;
h1 = h1.next;
} else {
current.next = h2;
h2 = h2.next;
}
current = current.next;
if (h2 == null && h1 != null) {
isH1Left = true;
break;
}
if (h1 == null && h2 != null) {
isH2Left = true;
break;
}
}
if (isH1Left) {
while (h1 != null) {
current.next = h1;
current = current.next;
h1 = h1.next;
}
}
if (isH2Left) {
while (h2 != null) {
current.next = h2;
current = current.next;
h2 = h2.next;
}
}
h3 = h3.next;
return h3;
}

I created only one dummy node at the beginning to save myself many 'if' conditions.
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode list1Cursor = l1;
ListNode list2Cursor = l2;
ListNode currentNode = new ListNode(-1); // Dummy node
ListNode head = currentNode;
while (list1Cursor != null && list2Cursor != null)
{
if (list1Cursor.val < list2Cursor.val) {
currentNode.next = list1Cursor;
list1Cursor = list1Cursor.next;
currentNode = currentNode.next;
} else {
currentNode.next = list2Cursor;
list2Cursor = list2Cursor.next;
currentNode = currentNode.next;
}
}
// Complete the rest
while (list1Cursor != null) {
currentNode.next = list1Cursor;
currentNode = currentNode.next;
list1Cursor = list1Cursor.next;
}
while (list2Cursor != null) {
currentNode.next = list2Cursor;
currentNode = currentNode.next;
list2Cursor = list2Cursor.next;
}
return head.next;
}

public ListNode MergeTwoLists(ListNode l1, ListNode l2) {//c#
ListNode _destNode=null;//Merged List
ListNode _srcNode=null;
ListNode _resHead=null;
if(l1==null || l2==null){//for scenario l1 null or l2 null or both null
return l1??l2??null;
}
if(l1.val<=l2.val){
_destNode=l1;//finding the dest list
_srcNode=l2;
_resHead=l1;
}
else{
_destNode=l2;
_srcNode=l1;
_resHead=l2;
}
while(_destNode!=null && _srcNode!=null){
if(_destNode.val<=_srcNode.val && (_destNode.next==null ||_destNode.next.val>=_srcNode.val)) {
//appending the values to dest list , if the element from dest list is less than element from _srcNode
var _temp_l2_currentnode=_srcNode;
_srcNode=_srcNode.next;
var _temp_l1_nextnode=_destNode.next;
_destNode.next=_temp_l2_currentnode;
_temp_l2_currentnode.next=_temp_l1_nextnode;
_destNode=_destNode.next;
}
else{
_destNode=_destNode.next;
}
}
return _resHead;
}

private static Node mergeLists(Node L1, Node L2) {
Node P1 = L1.val < L2.val ? L1 : L2;
Node P2 = L1.val < L2.val ? L2 : L1;
Node BigListHead = P1;
Node tempNode = null;
while (P1 != null && P2 != null) {
if (P1.next != null && P1.next.val >P2.val) {
tempNode = P1.next;
P1.next = P2;
P1 = P2;
P2 = tempNode;
} else if(P1.next != null)
P1 = P1.next;
else {
P1.next = P2;
break;
}
}
return BigListHead;
}

void printLL(){
NodeLL cur = head;
if(cur.getNext() == null){
System.out.println("LL is emplty");
}else{
//System.out.println("printing Node");
while(cur.getNext() != null){
cur = cur.getNext();
System.out.print(cur.getData()+ " ");
}
}
System.out.println();
}
void mergeSortedList(NodeLL node1, NodeLL node2){
NodeLL cur1 = node1.getNext();
NodeLL cur2 = node2.getNext();
NodeLL cur = head;
if(cur1 == null){
cur = node2;
}
if(cur2 == null){
cur = node1;
}
while(cur1 != null && cur2 != null){
if(cur1.getData() <= cur2.getData()){
cur.setNext(cur1);
cur1 = cur1.getNext();
}
else{
cur.setNext(cur2);
cur2 = cur2.getNext();
}
cur = cur.getNext();
}
while(cur1 != null){
cur.setNext(cur1);
cur1 = cur1.getNext();
cur = cur.getNext();
}
while(cur2 != null){
cur.setNext(cur2);
cur2 = cur2.getNext();
cur = cur.getNext();
}
printLL();
}

Here is the code on how to merge two sorted linked lists headA and headB:
Node* MergeLists1(Node *headA, Node* headB)
{
Node *p = headA;
Node *q = headB;
Node *result = NULL;
Node *pp = NULL;
Node *qq = NULL;
Node *head = NULL;
int value1 = 0;
int value2 = 0;
if((headA == NULL) && (headB == NULL))
{
return NULL;
}
if(headA==NULL)
{
return headB;
}
else if(headB==NULL)
{
return headA;
}
else
{
while((p != NULL) || (q != NULL))
{
if((p != NULL) && (q != NULL))
{
int value1 = p->data;
int value2 = q->data;
if(value1 <= value2)
{
pp = p->next;
p->next = NULL;
if(result == NULL)
{
head = result = p;
}
else
{
result->next = p;
result = p;
}
p = pp;
}
else
{
qq = q->next;
q->next = NULL;
if(result == NULL)
{
head = result = q;
}
else
{
result->next = q;
result = q;
}
q = qq;
}
}
else
{
if(p != NULL)
{
pp = p->next;
p->next = NULL;
result->next = p;
result = p;
p = pp;
}
if(q != NULL)
{
qq = q->next;
q->next = NULL;
result->next = q;
result = q;
q = qq;
}
}
}
}
return head;
}

Related

Recursion in Binary Search Tree construction

Below is the code implementation of binary search tree construction in C++. My confusion is I am not able to trace the recursion stack. Consider the below tree. Now I want to remove the node 10. SO this will jump to the line in the code that checks if both left and right subtree are not null and it will try to find the least value in the right subtree and that is 11 in this case. and it will recursively call remove function again . Now I have one doubt - when remove is recursively called again - first it removes 11 from that position in the original tree and return 11 from the function that is received by first remove function on the stack, but then which line in the code actually updates 11 to the root. I am really not getting this in my head. Please help me out.
10
/ \
6 12
\ / \
8 11 15
#include <bits/stdc++.h>
using namespace std;
class BST
{
public:
int value;
BST *left;
BST *right;
BST(int val)
{
value = val;
left = NULL;
right = NULL;
}
BST &insert(int val)
{
BST *currentNode = this; //this points to the current object of BST class. For instance if you created
//root node with value 10. this will store the reference to the root node object
while(true)
{
if (val < currentNode->value) //go to left subtree
{
if (currentNode->left == NULL) //if null insert
{
BST *newNode = new BST(val);
currentNode->left = newNode; //update the address
break;
}
else
{
currentNode = currentNode->left; //if not null then keep traversing
}
}
else
{
if (currentNode->right == NULL)
{
BST *newNode = new BST(val);
currentNode->right = newNode;
break;
}
else
{
currentNode = currentNode->right;
}
}
}
return *this;
}
bool contains(int val)
{
BST *currentNode = this;
while(currentNode != NULL)
{
if (val < currentNode->value)
currentNode = currentNode->left; //if value is less then keep traversing left
else if (val > currentNode->value)
currentNode = currentNode->right; //if value is greater then keep traversing right
else
return true;
}
return false;
}
BST &remove(int val, BST *parentNode = NULL)
{
BST *currentNode = this;
while (currentNode != NULL)
{
if (val < currentNode->value)
{
parentNode = currentNode;
currentNode = currentNode->left;
}
else if (val > currentNode->value)
{
parentNode = currentNode;
currentNode = currentNode->right;
}
//Up until above line the code first searches for the element to be removed
else
{
if (currentNode->left != NULL && currentNode->right != NULL) //this node checks if it has
//left and right child both and if yes then find the least value in the right subtree and then
//remove that node from that position
{
currentNode->value = currentNode->right->getMinValue();
currentNode->right->remove(currentNode->value,currentNode);
}
else if (parentNode == NULL) //this is special case of root node where there may be only
//left child existing or only right child. If both exist then above logic takes care of that
{
if (currentNode->left != NULL)
{
currentNode->value = currentNode->left->value;
currentNode->right = currentNode->left->right;
currentNode->left = currentNode->left->left;
}
else if (currentNode->right != NULL)
{
currentNode->value = currentNode->right->value;
currentNode->left = currentNode->right->left;
currentNode->right = currentNode->right->right;
}
else
{} //This is for single node tree. Do nothing
}
else if (parentNode->left == currentNode) //this condition if the parent node left child is
//the node to be removed . Then we can do simple one liner and update the node
{
parentNode->left = currentNode->left != NULL ? currentNode->left : currentNode->right;
}
else if (parentNode->right == currentNode)
{
parentNode->right = currentNode->left != NULL ? currentNode->left : currentNode->right;
}
break;
}
}
return *this;
}
int getMinValue()
{
if (left == NULL)
return value;
else
return left->getMinValue();
}
void show()
{
BST *currentNode = this;
cout<<currentNode->value;
}
};
int main()
{
int value = 10;
BST b1(value);
b1.insert(12);
b1.insert(6);
b1.insert(8);
b1.insert(15);
b1.insert(11);
b1.remove(10);
b1.show();
}

Red-Black Tree Deletion Partially Working

I implemented a red black tree in c++ with find, insert and delete. The delete only works for right side nodes and for the root node. I can't figure out why it isn't working for any of the left side nodes. Here is my code:
Node* searchNode(Node* root, int value){
Node* temp = root;
while (temp != NULL){
if (temp->val == value){
return temp;
}
else if (temp->val < value){
temp = temp->right;
}
else if (temp->val > value){
temp = temp->left;
}
}
}
Node* sibling(Node* node){
if ((node == NULL) || (node->parent == NULL)){
return NULL;
}
if (node == node->parent->left){
return node->parent->right;
}
else{
return node->parent->left;
}
}
Node* maxNode(Node* node){
while (node->right != NULL){
node = node->left;
}
return node;
}
void replaceNode(Node* old, Node* new_node){
if (old->parent == NULL){
old = new_node;
}
else{
if (old == old->parent->left){
old->parent->left = new_node;
}
else{
old->parent->right = new_node;
}
}
if (new_node != NULL){
new_node->parent = old->parent;
}
}
void deleteNode(Node* root, int value){
Node* child;
Node* temp = searchNode(root, value);
if (temp == NULL){
return;
}
if (temp->left != NULL&&temp->right != NULL){
Node* pred = maxNode(temp->right);
temp->val = pred->val;
temp = pred;
}
if (temp->left == NULL || temp->right == NULL){
if (temp->right == NULL && temp->left == NULL){
child = temp;
}
else if (temp->right == NULL){
child = temp->left;
}
else{
child = temp->right;
}
}
if (temp->color == 1){
temp->color = child->color;
delete_case1(root, child);
}
replaceNode(temp, child);
delete temp;
}
void delete_case6(Node* root, Node* n)
{
Node *s = sibling(n);
s->color = n->parent->color;
n->parent->color = 1;
if (n == n->parent->left) {
s->right->color = 1;
rotate_left(root, n->parent);
}
else {
s->left->color = 1;
rotate_right(root, n->parent);
}
}
void delete_case5(Node* root, Node* n)
{
Node *s = sibling(n);
if (s->color == 1) {
if ((n == n->parent->left) &&(s->right->color == 1) &&(s->left->color == 0)) {
s->color = 0;
s->left->color = 1;
rotate_right(root, s);
}else if ((n == n->parent->right) &&(s->left->color == 1) &&(s->right->color == 0)) {
s->color = 0;
s->right->color = 1;
rotate_left(root, s);
}
}
delete_case6(root, n);
}
void delete_case4(Node* root, Node* n)
{
Node *s = sibling(n);
if ((n->parent->color == 0) && (s->color == 1) && (s->left->color == 1) && (s->right->color == 1)) {
s->color = 0;
n->parent->color = 1;
}
else{
delete_case5(root, n);
}
}
void delete_case3(Node* root, Node* n){
Node* s = sibling(n);
if ((n->parent->color == 1) &&(s->color == 1) &&(s->left->color == 1) &&(s->right->color == 1)) {
s->color = 0;
delete_case1(root, n->parent);
}
else
delete_case4(root, n);
}
void delete_case2(Node* root, Node* n){
Node *s = sibling(n);
if (s->color == 0){
n->parent->color = 0;
s->color = 1;
if (n == n->parent->left){
rotate_left(root, n->parent);
}
else if (n == n->parent->right){
rotate_right(root, n->parent);
}
}
delete_case3(root, n);
}
void delete_case1(Node* root,Node* n){
if (n->parent != NULL){
delete_case2(root,n);
}
}
void main(){
ABTree* ABtree=new ABTree;
ABtree->root = NULL;
insertTree(ABtree->root, 15);
insertTree(ABtree->root, 8);
insertTree(ABtree->root, 2);
insertTree(ABtree->root, 9);
insertTree(ABtree->root, 10);
insertTree(ABtree->root, 12);
insertTree(ABtree->root, 18);
insertTree(ABtree->root, 25);
insertTree(ABtree->root, 20);
printTree(ABtree->root);
Node* search=searchNode(ABtree->root, 18);
cout << endl;
cout << search->val<<endl;
deleteNode(ABtree->root, 8);
printTree(ABtree->root);
}
For example if i want to delete either 8/9/2 the program crashes at delete_case4 at the if statement.
Thanks in advance!

How to convert a Ternary expression to a Binary tree structure?

I came across this problem that has Ternary expression (a?b:c) and needs the ternary expression to be converted into a Binary tree structure.
a?b:c
a
/ \
b c
a?b?c:d:e
a
/ \
b e
/ \
c d
My approach using a Binary tree implemented using a array :-
Parent resides at - i
Left child - 2i
Right child - 2i+1
Start parsing the ternary expression the first character will form the root node so it will be at position 1 in the array. If the next character is a '?' then the characters that follow will be its children so left child (b in this case will be at position 2). If the next character is a ":" then we have found the right child (c in the first case) so we add that to position 3.
In the second case we face a "?" after b so whatever follows will be its children and will be added to 2j and 2j+1 respectively where j is the position of b in the array.Now we face a ":" we check the parent of the current child if it has two children then we backtrack and check the previous node until we find a node that is missing a right child.
Is there any other way to do this? Hope I have been articulate enough.
Below is my solution which has been tested thoroughly.
class TreeNode {
char c;
TreeNode left;
TreeNode right;
TreeNode(char c) {
this.c = c;
left = null;
right = null;
}
}
public TreeNode tenaryToTree(String s) {
if (s.length() == 0) {
return null;
}
TreeNode root = new TreeNode(s.charAt(0));
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) == '?') {
TreeNode node = stack.peek();
node.left = new TreeNode(s.charAt(i + 1));
stack.push(node.left);
} else if (s.charAt(i) == ':') {
stack.pop();
TreeNode node = stack.pop();
node.right = new TreeNode(s.charAt(i + 1));
stack.push(node.right);
}
}
return root;
}
This one would be without using parent node. But using stack.
public NodeC convertTtoBT (char[] values) {
char xx = values[0];
NodeC n = new NodeC(xx);
Stack<NodeC> a = new Stack<NodeC>();
for (int i = 1; i < values.length; i += 2) {
if (values[i] == '?') {
n.left = new NodeC (values[i + 1]);
a.add(n);
n = n.left;
}
else if (values[i] == ':') {
n = a.pop();
while (n.right != null) {
n = a.pop();
}
n.right = new NodeC (values[i + 1]);
a.add(n);
n = n.right;
}
}
return n;
}
Walk through the expression from right to left, pushing any letters as nodes to the stack. If you see '?', then instead of pushing the next letter, take it as the root, pop two last nodes from the stack as left and right root's children, and push the root back into the stack.
public TreeNode ternaryToTree(char[] exp) {
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
for (int i = exp.length-1; i >= 0; i--) {
if (exp[i] == ':') continue;
if (exp[i] == '?') {
TreeNode node = new TreeNode(exp[--i]);
node.left = stack.pop();
node.right = stack.pop();
stack.push(node);
} else {
stack.push(new TreeNode(exp[i]));
}
}
return stack.isEmpty() ? null : stack.pop();
}
if this a?b:c?d?e:f:g?h:i?j:k is the ternary expression then tree would be like this
a
/ \
b c
/ \
d g
/ \ / \
e f h i
/ \
j k
Below is the Java solution...
private static TreeNode convertTernaryExpression(String s)
{
Stack<TreeNode> stack = new Stack<>();
int length = s.length();
int index = 0;
TreeNode rootNode = null;
while(index < length)
{
while(s.charAt(index) != ':')
{
if(s.charAt(index) == '?' && stack.peek().right != null)
{
TreeNode temp = stack.pop();
if(rootNode == null)
{
rootNode = temp;
}
stack.push(temp.right);
}
stack.push(new TreeNode(s.charAt(index++)));
}
TreeNode left = stack.pop();
TreeNode questionMark = stack.pop();
TreeNode root = stack.pop();
index++;
TreeNode right = new TreeNode(s.charAt(index++));
root.left = left;
root.right = right;
stack.push(root);
}
if(rootNode == null)
{
return stack.pop();
}
else
{
return rootNode;
}
}
class TreeNode
{
TreeNode left;
TreeNode right;
char val;
public TreeNode(char val)
{
this.val = val;
this.left = null;
this.right = null;
}
}
I came up with something like this using trees. Not tested thoroughly:
When I see a '?', it's my left child, so add to my left and go left.
If I see ':', then:
Go to my parent
If right is not null and parent is not not null, keep going to my parent
My right child is empty. Add right. Go to right.
Note: You will never go back to the root if it has a right child.
public NodeC convertTtoBT (char[] values) {
NodeC n = new NodeC (values[0]);
for (int i = 1; i < values.length; i += 2) {
if (values[i] == '?') {
n.left = new NodeC (values[i + 1]);
n = n.left;
}
else if (values[i] == ':') {
n = n.parent;
while (n.right != null && n.parent != null ) {
n = n.parent;
}
n.right = new NodeC (values[i + 1]);
n = n.right;
}
}
return n;
Idea is to start parsing the string from left to right and when you come across a '?' you go deeper in the tree else just return the new node created.
Here is my recursive solution :
struct node{
char val;
node *left;
node *right;
node(char v):val(v),left(NULL),right(NULL){
}
};
node* create_tree(string input, int &current){
if(current>=(int)input.size()){
return NULL;
}
node *temp = new node(input[current]);
current+=2;
if(current<(int)input.size()){
if(input[current-1]=='?'){
temp->left=create_ternary_tree(input,current);
temp->right=create_ternary_tree(input,current);
}
}
return temp;
}
My solution:
Each treenode doen't have parent link, so I use stack to keep them.
The advantages of this solution are that I only push root into stack, hence in the (if x==':' {}) sentence, no while loop, no push sentence.
public static TreeNode convert(String ternary) {
char[] chs = ternary.toCharArray();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur=new TreeNode(chs[0]);
TreeNode root= cur;
for (int i=1; i<chs.length; i+=2) {
if (chs[i]=='?') {
stack.push(cur);
TreeNode node = new TreeNode(chs[i+1]);
cur.left = node;
cur = node;
}
else if (chs[i]==':') {
cur = stack.pop();
TreeNode node = new TreeNode(chs[i+1]);
cur.right = node;
cur = node;
}
}
return root;
}
public static TreeNode convert_loop(char[] expr) {
if (expr == null || expr.length < 1) {
return null;
}
if (expr.length == 1) {
return new TreeNode(expr[0]);
}
if ((expr.length - 1) % 4 != 0) {
throw new InputMismatchException("wrong expression");
}
int start = 0, end = expr.length - 1;
TreeNode<Character> root = new TreeNode<>(expr[start]);
root.right = new TreeNode<>(expr[end]);
start += 2;
end -= 2;
TreeNode<Character> cur = root;
while (start != end) {
TreeNode<Character> node = new TreeNode<>(expr[start]);
node.right = new TreeNode<>(expr[end]);
cur.left = node;
cur = node;
start += 2;
end -= 2;
}
cur.left = new TreeNode(expr[start]);// care
return root;
}

Find Ancestor method for binary search tree is not working

I had written the method for finding a node's parent in C# (c-sharp) but my code is not working correctly. Exceptions: System.NullReferenceException is thrown when I try to delete a node who's parent is null.
public TreeNode FindParent(int value, ref TreeNode parent)
{
TreeNode currentNode = root;
if (currentNode == null)
{
return null;
}
while (currentNode.value != value)
{
if (value < currentNode.value)
{
parent = currentNode;
currentNode = currentNode.leftChild;
}
if (value > currentNode.value)
{
parent = currentNode;
currentNode = currentNode.rightChild;
}
}
return currentNode;
}
public void Delete(int value)
{
TreeNode parent = null;
TreeNode nodeToDelete = FindParent(value, ref parent);
if (nodeToDelete == null)
{
throw new Exception("Unable to delete node: " + value.ToString());
}
//CASE 1: Nod has 0 children.
if (nodeToDelete.leftChild == null && nodeToDelete.rightChild == null)
{
if (parent.leftChild == nodeToDelete)
{
parent.leftChild = null;
}
if (parent.rightChild == nodeToDelete)
{
parent.rightChild = null;
}
count--;
return;
}
//CASE 2: Nod has 1 left || 1 right barn
if (nodeToDelete.leftChild == null && nodeToDelete.rightChild != null)
{
nodeToDelete.rightChild = parent.rightChild;
nodeToDelete = null;
count--;
return;
}
if (nodeToDelete.leftChild != null && nodeToDelete.rightChild == null)
{
nodeToDelete.leftChild = parent.leftChild;
nodeToDelete = null;
count--;
return;
}
//CASE 3: Nod has 2 children
if (nodeToDelete.rightChild != null && nodeToDelete.leftChild != null)
{
TreeNode successor = LeftMostNodeOnRight(nodeToDelete, ref parent);
TreeNode temp = new TreeNode(successor.value);
if (parent.leftChild == successor)
{
parent.leftChild = successor.rightChild;
}
else
{
parent.rightChild = successor.rightChild; nodeToDelete.value = temp.value;
}
count--;
return;
}
}
since you are using recursion , you don't need the parent Node to delete a node in a binary search tree, here is a delete method where you pass in int and the root
private BinaryTreeNode remove (int value, TreeNode t){
if(t==null)
return t; // not found; do nothing
if(value < t.value){
t.left = remove(x,y,t.left);
}
else if (value > t.value){
t.right = remove(x,y,t.right);
}
else if( t.left!=null && t.right != null) // two children
{
t.info = findMin(t.right).info;
remove(t.info.getLastName(),y,t.right);
}
else{ // one child
if (t.left != null) {
t = t.left;
}
else{
t = t.right;
}
}
return t;
}
Edit-----------findMin (find minimum node in a binary search tree)
private BinaryTreeNode findMin ( BinaryTreeNode t){ // recursive
if(t == null)
return null;
else if (t.left == null)
return t;
return findMin(t.left);
}
So you take the min value from the right subtree, and make it the parent of t.info. Follow these diagrams. We are deleting node 25 with two children.

Add to numbers represented by a linked list - Edge case

I was reading the algorithm to add two numbers represented by a linked list from the book Crack The Coding Interview by Gayle Laakmann on page 108. If you don't have the book the question, algorithm and code is as follows:
Question
You have two numbers represented by a linked list, where each node
contains a single digit. The digits are stored in reverse order, such
that the 1's digit is at the head of the list. Write a function that
adds the two numbers and returns the um as a linked list.
Example
Input: (3->1->5),(5->9->2)
Output: 8->0->8
Algorithm
result.data = (node1 + node2 +earlier carry) % 10
if node1 + node2 > 10, then carry a 1 to the next addition
add the tails of the two nodes, passing along the carry
Code
LinkedListNode addLists(LinkedListNode l1, LinkedListNode l2, int carry) {
if (l1 == null && l2 == null) {
return null;
}
LinkedListNode result = new LinkedListNode(carry, null, null);
int value = carry;
if (l1 != null) {
value += l1.data;
}
if (l2 != null) {
value += l2.data;
}
result.data = value % 10;
LinkedListNode more = addLists(l1 == null ? null : l1.next, l2 == null ? null : l2.next, value > 10 ? 1 : 0);
result.setNext(more);
return result;
}
The obvious thing that comes to mind after seeing if (l1 == null && l2 == null) is that what if both the digits are null and there is still a carry - like when we are adding 999 + 999. Wouldn't that result in a wrong answer? If that results ina right answer, I fail to see how. If that results in a wrong answer, how can we get the correct answer? Would changing the first few lines to
LinkedListNode addLists(LinkedListNode l1, LinkedListNode l2, int carry = null) {
if (l1 == null && l2 == null) {
return carry;
}
do the trick?
The condition should be:
value > 9 ? 1 : 0
in following recursive call:
LinkedListNode more = addLists(l1 == null ? null : l1.next, l2 == null ? null : l2.next, value > 10 ? 1 : 0);
// space
Here is my solution that works:
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
return addTwoNumbers(l1, l2, 0);
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2, int carry) {
int value;
if(carry > 0) {
// handle negative values for carry
value = carry;
} else {
value = 0;
}
if(l1 == null && l2 == null){
if(value > 0) {
// here we have only carry to bother.
// if it is zero, no need to create node
return new ListNode(value);
} else {
return null;
}
}
if(l1 != null){
value += l1.val;
}
if(l2 != null){
value += l2.val;
}
carry = value/10;
ListNode n1 = new ListNode(value%10);
n1.next = addTwoNumbers(l1 != null ? l1.next : null, l2 != null ? l2.next : null, carry);
return n1;
}
}
My Solution Using DList!
public class DListNode {
public int item;
public DListNode prev;
public DListNode next;
DListNode() {
item = 0;
prev = null;
next = null;
}
public DListNode(int i){
item = i;
prev = null;
next = null;
}
}
Second class:
public class DList {
protected DListNode head;
protected DListNode tail;``
protected long size;
public DList() {
head = null;
tail = null;
size = 0;
}
public DList(int a) {
head = new DListNode();
tail = head;
head.item = a;
size = 1;
}
public DList(int a, int b) {
head = new DListNode();
head.item = a;
tail = new DListNode();
tail.item = b;
head.next = tail;
tail.prev = head;
size = 2;
}
public void insertFront(int i) {
if (size == 0) {
head = new DListNode(i);
tail = head;
} else {
DListNode temp = new DListNode(i);
head.prev = temp;
temp.next = head;
head = temp;
}
size++;
}
public String toString() {
String result = "[ ";
DListNode current = head;
while (current != null) {
result = result + current.item + " ";
current = current.next;
}
return result + "]";
}
public long getSize() {
return size;
}
public DListNode getHead() {
return head;
}
public DListNode getTail() {
return tail;
}
public DList addList(DList lst1, DList lst2) {
DList result = new DList();
DListNode tail1 = lst1.getTail();
DListNode tail2 = lst2.getTail();
int carry = 0;
if (lst1 == null || lst2 == null) {
return null;
}
if (lst1.getSize() != lst2.getSize()) {
if (lst1.getSize() < lst2.getSize()) {
long diff = lst2.getSize() - lst1.getSize();
long a = 0;
while (a < diff) {
lst1.insertFront(0);
a++;
}
} else {
long diff = lst1.getSize() - lst2.getSize();
long a = 0;
while (a < diff) {
lst2.insertFront(0);
a++;
}
}
}
int a = 0;
int resultValue;
while (a <= lst1.getSize()) {
if (tail1 != null && tail2 != null) {
int l1 = tail1.item;
int l2 = tail2.item;
int sum = carry + l1 + l2;
if (a == lst1.getSize() - 1) {
resultValue = sum % 10;
carry = 1;
result.insertFront(carry);
result.insertFront(resultValue);
} else if (sum >= 10) {
resultValue = sum % 10;
carry = 1;
result.insertFront(resultValue);
}
else {
resultValue = sum;
carry = 0;
result.insertFront(resultValue);
}
//result.insertFront(resultValue);
tail1 = tail1.prev;
tail2 = tail2.prev;
}
a++;
}
System.out.println("List1 is: " + lst1.toString());
System.out.println("List2 is: " + lst2.toString());
return result;
}
public static void main(String[] args) {
DList d1 = new DList();
DList d2 = new DList();
d1.insertFront(1);
d1.insertFront(5);
d1.insertFront(3);
d2.insertFront(4);
d2.insertFront(5);
d2.insertFront(7);
DList d3 = new DList();
System.out.println(d3.addList(d1, d2));
}
}
Node* addReversed(Node *l1, Node *l2, int carry) {
if (l1 == NULL && l2 == NULL && carry == 0) return NULL;
int value = carry;
if (l1 != NULL)
value += l1->data;
if (l2 != NULL)
value += l2->data;
Node *answer = new Node(value%10);
if (l1 != NULL || l2 != NULL) {
Node *temp = addReversed(l1 != NULL ? l1->next : NULL, l2 != NULL ? l2->next : NULL, value >= 10 ? 1 : 0);
answer->next = temp;
} else {
if (value >= 10) {
Node *temp = new Node(1);
answer->next = temp;
}
}
return answer;
}
Basically, the last if condition checks if the addition is over and there was still a carry left. If that is the case then it is added to a node of its own and appended to the answer.
My solution using Python3
class Node:
def __init__(self, value):
self.value = value
self.next = None
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
def addNode(self, inse):
nde = Node(inse)
if self.head == None:
self.head = nde
self.tail = nde
else:
self.tail.next = nde
self.tail = nde
def __str__(self):
nodestore = [str(self.head.value)]
index = self.head
while index.next != None:
index = index.next
nodestore.append(str(index.value))
return "->".join(nodestore)
def addTwo(self, fi, se):
self.head = None
self.tail = None
carry = 0
while (fi is not None or se is not None):
fdata = 0 if fi is None else fi.value
sdata = 0 if se is None else se.value
Sum = carry + fdata + sdata
carry = 1 if Sum >= 10 else 0
Sum = Sum if Sum < 10 else Sum % 10
temp = Node(Sum)
if self.head == None:
self.head = temp
else:
self.tail.next = temp
self.tail = temp
if fi is not None:
fi = fi.next
if se is not None:
se = se.next
if carry > 0: #for first digit = 1
self.tail.next = Node(carry)
def randomLinkedList(leng, min, max):
from random import randint
rll = LinkedList()
for i in range(leng):
value = randint(min, max)
rll.addNode(value)
return rll
l1 = randomLinkedList(3,0,9)
l2 = randomLinkedList(3,0,9)
print (l1)
print (l2)
res = LinkedList()
res.addTwo(l1.head, l2.head)
print (res)

Resources